[llvm] [LoopIdiomRecognize] Enable clmul optimization for CRC loops (PR #203405)

Sean Clarke via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 10:53:21 PDT 2026


https://github.com/xarkenz updated https://github.com/llvm/llvm-project/pull/203405

>From 88d9c0eb0c736b0d4b122e656fe4a7f675996df9 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Thu, 11 Jun 2026 10:28:06 -0500
Subject: [PATCH 01/18] Enable clmul optimization for CRC loops

---
 llvm/include/llvm/Analysis/HashRecognize.h    |  22 ++++
 .../llvm/Analysis/TargetTransformInfo.h       |   4 +
 .../llvm/Analysis/TargetTransformInfoImpl.h   |   2 +
 llvm/include/llvm/CodeGen/BasicTTIImpl.h      |   7 ++
 llvm/lib/Analysis/HashRecognize.cpp           |  52 ++++++++
 llvm/lib/Analysis/TargetTransformInfo.cpp     |   4 +
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 119 +++++++++++++++---
 .../HashRecognize/cyclic-redundancy-check.ll  |  20 +++
 8 files changed, 211 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/Analysis/HashRecognize.h b/llvm/include/llvm/Analysis/HashRecognize.h
index e88737ea31058..edd7059725409 100644
--- a/llvm/include/llvm/Analysis/HashRecognize.h
+++ b/llvm/include/llvm/Analysis/HashRecognize.h
@@ -35,6 +35,23 @@ struct CRCTable : public std::array<APInt, 256> {
 #endif
 };
 
+/// The constants used to perform polynomial division with a Barrett-style
+/// reduction into two polynomial multiplications instead.
+struct CRCBarrettConstants {
+  // An approximation of the polynomial quotient floor(x^2w / P(x)), where P(x)
+  // is the generating polynomial and w is the CRC width.
+  APInt Reciprocal;
+
+  // The generating polynomial P(x) in full, adjusted for endianness.
+  APInt Generator;
+
+  LLVM_ABI void print(raw_ostream &OS) const;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+  LLVM_ABI LLVM_DUMP_METHOD void dump() const;
+#endif
+};
+
 /// The structure that is returned when a polynomial algorithm was recognized by
 /// the analysis. Currently, only the CRC algorithm is recognized.
 struct PolynomialInfo {
@@ -88,6 +105,11 @@ class HashRecognize {
   LLVM_ABI static CRCTable genSarwateTable(const APInt &GenPoly,
                                            bool IsBigEndian);
 
+  // Auxilary entry point after analysis to generate constants for a
+  // Barrett-style reduction.
+  LLVM_ABI static CRCBarrettConstants
+  genBarrettConstants(const APInt &GenPoly, bool ByteOrderSwapped);
+
   LLVM_ABI void print(raw_ostream &OS) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 10c0509460b95..d6ce82219ad12 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1185,6 +1185,10 @@ class TargetTransformInfo {
   /// Return true if the hardware has a fast square-root instruction.
   LLVM_ABI bool haveFastSqrt(Type *Ty) const;
 
+  /// Return true if the hardware has a fast carryless-multiplication
+  /// instruction.
+  LLVM_ABI bool haveFastClmul(Type *Ty) const;
+
   /// Return true if the cost of the instruction is too high to speculatively
   /// execute and should be kept behind a branch.
   /// This normally just wraps around a getInstructionCost() call, but some
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 5645cc63a6944..a60e7e9a85508 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -570,6 +570,8 @@ class LLVM_ABI TargetTransformInfoImplBase {
 
   virtual bool haveFastSqrt(Type *Ty) const { return false; }
 
+  virtual bool haveFastClmul(Type *Ty) const { return false; }
+
   virtual bool isExpensiveToSpeculativelyExecute(const Instruction *I) const {
     return true;
   }
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 55163eb1976bf..c369c928b9eb4 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -676,6 +676,13 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
            TLI->isOperationLegalOrCustom(ISD::FSQRT, VT);
   }
 
+  bool haveFastClmul(Type *Ty) const override {
+    const TargetLoweringBase *TLI = getTLI();
+    EVT VT = TLI->getValueType(DL, Ty);
+    return TLI->isTypeLegal(VT) &&
+           TLI->isOperationLegalOrCustomOrPromote(ISD::CLMUL, VT);
+  }
+
   bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override { return true; }
 
   InstructionCost getFPOpCost(Type *Ty) const override {
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index fcd8fbaa138a7..623571636a9fa 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -376,6 +376,48 @@ CRCTable HashRecognize::genSarwateTable(const APInt &GenPoly,
   return Table;
 }
 
+// Divide one GF(2) polynomial by another.
+static APInt calculateGF2Quotient(APInt Dividend, const APInt &Divisor) {
+  unsigned DivisorDeg = Divisor.getActiveBits() - 1;
+  APInt Quotient = APInt::getZero(Dividend.getBitWidth());
+  unsigned DividendDeg;
+  while (!Dividend.isZero() &&
+         (DividendDeg = Dividend.getActiveBits() - 1) >= DivisorDeg) {
+    unsigned Shift = DividendDeg - DivisorDeg;
+    Quotient.setBit(Shift);
+    Dividend ^= Divisor.shl(Shift);
+  }
+  return Quotient;
+}
+
+// Generate constants (mu/reciprocal, P/generator) for a Barrett-style
+// reduction. This reduction allows the Sarwate table entry to be computed on
+// the fly, rather than requiring a load from memory (on supporting hardware).
+CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
+                                                       bool ByteOrderSwapped) {
+  unsigned BW = GenPoly.getBitWidth();
+  unsigned ClmulBW = BW * 2;
+  unsigned DivBW = ClmulBW + 1;
+  APInt Dividend = APInt::getSignedMinValue(DivBW);
+  CRCBarrettConstants C;
+
+  if (ByteOrderSwapped) {
+    APInt G = GenPoly.zext(DivBW);
+    G.setBit(BW);
+    APInt Mu = calculateGF2Quotient(Dividend, G);
+    C.Reciprocal = Mu.trunc(ClmulBW);
+    C.Generator = G.trunc(ClmulBW);
+    return C;
+  }
+
+  APInt G = GenPoly.reverseBits().zext(DivBW);
+  G.setBit(BW);
+  APInt Mu = calculateGF2Quotient(Dividend, G);
+  C.Reciprocal = Mu.trunc(BW + 1).reverseBits().zext(ClmulBW).getLoBits(8);
+  C.Generator = GenPoly.zext(ClmulBW).shl(1);
+  return C;
+}
+
 /// Checks that \p P1 and \p P2 are used together in an XOR in the use-def chain
 /// of \p SI's condition, ignoring any casts. The purpose of this function is to
 /// ensure that LHSAux from the SimpleRecurrence is used correctly in the CRC
@@ -531,6 +573,14 @@ void CRCTable::print(raw_ostream &OS) const {
 void CRCTable::dump() const { print(dbgs()); }
 #endif
 
+void CRCBarrettConstants::print(raw_ostream &OS) const {
+  OS << "Reciprocal = " << Reciprocal << ", Generator = " << Generator << '\n';
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+void CRCBarrettConstants::dump() const { print(dbgs()); }
+#endif
+
 void HashRecognize::print(raw_ostream &OS) const {
   if (!L.isInnermost())
     return;
@@ -565,6 +615,8 @@ void HashRecognize::print(raw_ostream &OS) const {
   }
   OS.indent(2) << "Computed CRC lookup table:\n";
   genSarwateTable(Info.RHS, Info.IsBigEndian).print(OS);
+  OS.indent(2) << "Computed CRC Barrett constants:\n";
+  genBarrettConstants(Info.RHS, Info.IsBigEndian).print(OS);
 }
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index cdccd04f4c9ea..02a9a865ddc88 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -743,6 +743,10 @@ bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
   return TTIImpl->haveFastSqrt(Ty);
 }
 
+bool TargetTransformInfo::haveFastClmul(Type *Ty) const {
+  return TTIImpl->haveFastClmul(Ty);
+}
+
 bool TargetTransformInfo::isExpensiveToSpeculativelyExecute(
     const Instruction *I) const {
   return TTIImpl->isExpensiveToSpeculativelyExecute(I);
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index f99dad18aa5c9..02a7bbb8d752a 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -202,6 +202,8 @@ class LoopIdiomRecognize {
 private:
   using StoreList = SmallVector<StoreInst *, 8>;
   using StoreListMap = MapVector<Value *, StoreList>;
+  using CRCTableFn =
+      function_ref<Value *(IRBuilderBase &Builder, Value *Indexer)>;
 
   StoreListMap StoreRefsForMemset;
   StoreListMap StoreRefsForMemsetPattern;
@@ -259,6 +261,9 @@ class LoopIdiomRecognize {
   bool avoidLIRForMultiBlockLoop(bool IsMemset = false,
                                  bool IsLoopMemset = false);
   bool optimizeCRCLoop(const PolynomialInfo &Info);
+  bool optimizeCRCLoopWithFastClmul(const PolynomialInfo &Info);
+  void buildReducedCRCLoop(const PolynomialInfo &Info,
+                           CRCTableFn GetTableEntry);
 
   /// @}
   /// \name Noncountable Loop Idiom Handling
@@ -1560,10 +1565,14 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
   if (TT.getArch() == Triple::hexagon)
     return false;
 
+  // If using llvm.clmul would be more efficient, use that instead of a lookup
+  // table.
+  if (optimizeCRCLoopWithFastClmul(Info))
+    return true;
+
   // First, create a new GlobalVariable corresponding to the
   // Sarwate-lookup-table.
   Type *CRCTy = Info.LHS->getType();
-  unsigned CRCBW = CRCTy->getIntegerBitWidth();
   std::array<Constant *, 256> CRCConstants;
   transform(HashRecognize::genSarwateTable(Info.RHS, Info.IsBigEndian),
             CRCConstants.begin(),
@@ -1574,10 +1583,94 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
       new GlobalVariable(M, ConstArray->getType(), true,
                          GlobalValue::PrivateLinkage, ConstArray, ".crctable");
 
+  // Build a reduced per-byte loop which loads an entry from the Sarwate lookup
+  // table each iteration.
+  //
+  // Little-endian:
+  //   crc = (crc >> 8) ^ tbl[(iv'th byte of data) ^ (bottom byte of crc)]
+  // Big-Endian:
+  //   crc = (crc << 8) ^ tbl[(iv'th byte of data) ^ (top byte of crc)]
+  buildReducedCRCLoop(Info, [&](auto &Builder, Value *Indexer) {
+    // Always index into a GEP using the index type.
+    Indexer = Builder.CreateZExt(
+        Indexer, SE->getDataLayout().getIndexType(GV->getType()),
+        "indexer.ext");
+
+    // CRCTableLd = CRCTable[(iv'th byte of data) ^ (top|bottom) byte of CRC].
+    Value *CRCTableGEP =
+        Builder.CreateInBoundsGEP(CRCTy, GV, Indexer, "tbl.ptradd");
+    Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP, "tbl.ld");
+
+    return CRCTableLd;
+  });
+
+  return true;
+}
+
+bool LoopIdiomRecognize::optimizeCRCLoopWithFastClmul(
+    const PolynomialInfo &Info) {
+  Type *CRCTy = Info.LHS->getType();
+  unsigned CRCBW = CRCTy->getIntegerBitWidth();
+  Type *ClmulTy = IntegerType::get(CRCTy->getContext(), 2 * CRCBW);
+
+  // Only apply this optimization strategy if llvm.clmul would lower into a
+  // native instruction.
+  if (!TTI->haveFastClmul(ClmulTy))
+    return false;
+
+  // First, generate the two constants required for a Barrett-style reduction.
+  CRCBarrettConstants Constants =
+      HashRecognize::genBarrettConstants(Info.RHS, Info.ByteOrderSwapped);
+  Value *Reciprocal = ConstantInt::get(ClmulTy, Constants.Reciprocal);
+  Value *Generator = ConstantInt::get(ClmulTy, Constants.Generator);
+
+  // Build a reduced per-byte loop which computes the lookup table entry on the
+  // fly each iteration using a Barrett-style reduction.
+  //
+  // Little-endian:
+  //   q = ((iv'th byte of data) ^ (bottom byte of crc)) clmul (reciprocal term)
+  //   entry = (bottom byte of q) clmul (generator term)
+  //   crc = (crc >> 8) ^ (top byte of entry)
+  // Big-Endian:
+  //   q = ((iv'th byte of data) ^ (top byte of crc)) clmul (reciprocal term)
+  //   entry = (top byte of q) clmul (generator term)
+  //   crc = (crc << 8) ^ (bottom byte of entry)
+  buildReducedCRCLoop(Info, [&](auto &Builder, Value *Indexer) {
+    // Approximate floor(Indexer / (generator term)) using Indexer * (reciprocal
+    // term).
+    Indexer = Builder.CreateZExt(Indexer, ClmulTy, "indexer.ext");
+    Value *Quotient = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, Indexer,
+                                                    Reciprocal, {}, "quot");
+    Quotient = Info.ByteOrderSwapped
+                   ? Builder.CreateLShr(Quotient, CRCBW, "quot.be.shift")
+                   : Builder.CreateAnd(Quotient, 0xFF, "quot.le.mask");
+
+    // floor(Indexer / (generator term)) * (generator term) should give us what
+    // the Sarwate table entry would be.
+    Value *Entry = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, Quotient,
+                                                 Generator, {}, "entry");
+    Entry =
+        Info.ByteOrderSwapped
+            ? Builder.CreateAnd(Entry, APInt::getLowBitsSet(2 * CRCBW, CRCBW),
+                                "entry.be.mask")
+            : Builder.CreateLShr(Entry, 8, "entry.le.shift");
+    Entry = Builder.CreateTrunc(Entry, CRCTy, "entry.cast");
+
+    return Entry;
+  });
+
+  return true;
+}
+
+void LoopIdiomRecognize::buildReducedCRCLoop(
+    const PolynomialInfo &Info, LoopIdiomRecognize::CRCTableFn GetTableEntry) {
+  Type *CRCTy = Info.LHS->getType();
+  unsigned CRCBW = CRCTy->getIntegerBitWidth();
+
   PHINode *IV = CurLoop->getCanonicalInductionVariable();
   SmallVector<PHINode *, 2> Cleanup;
 
-  // Next, mark all PHIs for removal except IV.
+  // First, mark all PHIs for removal except IV.
   {
     for (PHINode &PN : CurLoop->getHeader()->phis()) {
       if (&PN == IV)
@@ -1606,11 +1699,6 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
 
   // Finally, fill the loop with the Sarwate-table-lookup logic, and replace all
   // uses of ComputedValue.
-  //
-  // Little-endian:
-  //   crc = (crc >> 8) ^ tbl[(iv'th byte of data) ^ (bottom byte of crc)]
-  // Big-Endian:
-  //   crc = (crc << 8) ^ tbl[(iv'th byte of data) ^ (top byte of crc)]
   {
     auto LoByte = [](IRBuilderBase &Builder, Value *Op, const Twine &Name) {
       return Builder.CreateZExtOrTrunc(
@@ -1664,24 +1752,18 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
     Indexer = Info.IsBigEndian ? HiIdx(Builder, Indexer, "indexer.hi")
                                : LoByte(Builder, Indexer, "indexer.lo");
 
-    // Always index into a GEP using the index type.
-    Indexer = Builder.CreateZExt(
-        Indexer, SE->getDataLayout().getIndexType(GV->getType()),
-        "indexer.ext");
-
-    // CRCTableLd = CRCTable[(iv'th byte of data) ^ (top|bottom) byte of CRC].
-    Value *CRCTableGEP =
-        Builder.CreateInBoundsGEP(CRCTy, GV, Indexer, "tbl.ptradd");
-    Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP, "tbl.ld");
+    // Get the Sarwate lookup table entry corresponding to Indexer. This could
+    // either be a load or an on-the-fly computation, so let the caller decide.
+    Value *CRCTableEntry = GetTableEntry(Builder, Indexer);
 
     // CRCNext = (CRC (<<|>>) 8) ^ CRCTableLd, or simply CRCTableLd in case of
     // CRC-8.
-    Value *CRCNext = CRCTableLd;
+    Value *CRCNext = CRCTableEntry;
     if (CRCBW > 8) {
       Value *CRCShift = Info.IsBigEndian
                             ? Builder.CreateShl(CRC, 8, "crc.be.shift")
                             : Builder.CreateLShr(CRC, 8, "crc.le.shift");
-      CRCNext = Builder.CreateXor(CRCShift, CRCTableLd, "crc.next");
+      CRCNext = Builder.CreateXor(CRCShift, CRCTableEntry, "crc.next");
     }
 
     // Connect the back-edge for the loop, and RAUW the ComputedValue.
@@ -1696,7 +1778,6 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
       RecursivelyDeleteDeadPHINode(PN);
     SE->forgetLoop(CurLoop);
   }
-  return true;
 }
 
 bool LoopIdiomRecognize::runOnNoncountableLoop() {
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index 78b4139d21982..8ea699852fe48 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -25,6 +25,8 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  39937 23744 23936 40257 24320 40897 40577 24128 23040 39617 39809 23360 39169 22976 22656 38977
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 255, Generator = 81922
 ;
 entry:
   br label %loop
@@ -73,6 +75,8 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  39937 23744 23936 40257 24320 40897 40577 24128 23040 39617 39809 23360 39169 22976 22656 38977
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 255, Generator = 81922
 ;
 entry:
   br label %loop
@@ -121,6 +125,8 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; CHECK-NEXT:  39937 23744 23936 40257 24320 40897 40577 24128 23040 39617 39809 23360 39169 22976 22656 38977
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 255, Generator = 81922
 ;
 entry:
   br label %loop
@@ -168,6 +174,8 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; CHECK-NEXT:  4 13 22 31 27 18 9 0 1 8 19 26 30 23 12 5
 ; CHECK-NEXT:  26 19 8 1 5 12 23 30 31 22 13 4 0 9 18 27
 ; CHECK-NEXT:  16 25 2 11 15 6 29 20 21 28 7 14 10 3 24 17
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 103, Generator = 58
 ;
 entry:
   br label %loop
@@ -215,6 +223,8 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; CHECK-NEXT:  52093 56156 60223 64286 35833 39896 43963 48026 19061 23124 27191 31254 2801 6864 10931 14994
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 69936, Generator = 69665
 ;
 entry:
   %msg.ext = zext i8 %msg to i16
@@ -260,6 +270,8 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; CHECK-NEXT:  52093 56156 60223 64286 35833 39896 43963 48026 19061 23124 27191 31254 2801 6864 10931 14994
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 69936, Generator = 69665
 ;
 entry:
   br label %loop
@@ -302,6 +314,8 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; CHECK-NEXT:  52093 56156 60223 64286 35833 39896 43963 48026 19061 23124 27191 31254 2801 6864 10931 14994
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 69936, Generator = 69665
 ;
 entry:
   br label %loop
@@ -344,6 +358,8 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; CHECK-NEXT:  248 229 194 223 140 145 182 171 16 13 42 55 100 121 94 67
 ; CHECK-NEXT:  178 175 136 149 198 219 252 225 90 71 96 125 46 51 20 9
 ; CHECK-NEXT:  127 98 69 88 11 22 49 44 151 138 173 176 227 254 217 196
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 284, Generator = 285
 ;
 entry:
   br label %outer.loop
@@ -404,6 +420,8 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; CHECK-NEXT:  54925 50948 62879 58390 37033 33056 46011 41522 23237 19276 31191 26718 7393 3432 16371 11898
 ; CHECK-NEXT:  59150 63111 50204 54677 41258 45219 33336 37809 27462 31439 18516 23005 11618 15595 3696 8185
 ; CHECK-NEXT:  63375 58886 54429 50452 45483 40994 37561 33584 31687 27214 22741 18780 15843 11370 7921 3960
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 17, Generator = 67600
 ;
 entry:
   br label %loop
@@ -451,6 +469,8 @@ define i16 @crc16.be.tc8.zext.data(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  53664 53410 54180 53926 54696 54442 55212 54958 55728 55474 56244 55990 56760 56506 57276 57022
 ; CHECK-NEXT:  57792 57538 58308 58054 58824 58570 59340 59086 59856 59602 60372 60118 60888 60634 61404 61150
 ; CHECK-NEXT:  61920 61666 62436 62182 62952 62698 63468 63214 63984 63730 64500 64246 65016 64762 65532 65278
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Reciprocal = 65795, Generator = 65794
 ;
 entry:
   br label %loop

>From d61e0720606e065683db951ec914533dbd56fb80 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Fri, 12 Jun 2026 09:21:15 -0500
Subject: [PATCH 02/18] Add CRC tests for X86, AArch64, RISCV

---
 .../AArch64/cyclic-redundancy-check.ll        |  833 +++++++++++++
 .../RISCV/cyclic-redundancy-check.ll          | 1105 +++++++++++++++++
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  |  836 +++++++++++++
 3 files changed, 2774 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
 create mode 100644 llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
 create mode 100644 llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll

diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
new file mode 100644
index 0000000000000..cbda266771fd3
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -0,0 +1,833 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
+; RUN: opt -passes=loop-idiom -mtriple=aarch64 -mattr=-aes -S %s | FileCheck --check-prefixes=ALL,NOAES %s
+; RUN: opt -passes=loop-idiom -mtriple=aarch64 -mattr=+aes -S %s | FileCheck --check-prefixes=ALL,AES %s
+
+;.
+; NOAES: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOAES: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOAES: @.crctable.2 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOAES: @.crctable.3 = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
+; NOAES: @.crctable.4 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOAES: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOAES: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOAES: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOAES: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+;.
+; AES: @.crctable = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
+; AES: @.crctable.1 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+;.
+define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
+; NOAES-LABEL: define i16 @crc16.le.tc8(
+; NOAES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOAES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.le.tc8(
+; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; AES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %and.data.crc = and i8 %xor.data.crc, 1
+  %data.next = lshr i8 %data, 1
+  %check.sb = icmp eq i8 %and.data.crc, 0
+  %crc.lshr = lshr i16 %crc, 1
+  %xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
+; NOAES-LABEL: define i16 @crc16.le.tc8.udiv(
+; NOAES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOAES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.le.tc8.udiv(
+; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; AES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %and.data.crc = and i8 %xor.data.crc, 1
+  %data.next = udiv i8 %data, 2
+  %check.sb = icmp eq i8 %and.data.crc, 0
+  %crc.lshr = udiv i16 %crc, 2
+  %xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
+; NOAES-LABEL: define i16 @crc16.le.tc16(
+; NOAES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOAES-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.le.tc16(
+; AES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; AES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; AES-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %and.crc.data = and i16 %xor.crc.data, 1
+  %data.next = lshr i16 %data, 1
+  %check.sb = icmp eq i16 %and.crc.data, 0
+  %crc.lshr = lshr i16 %crc, 1
+  %crc.xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
+; NOAES-LABEL: define i8 @crc8.le.tc16(
+; NOAES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOAES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOAES-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i8 @crc8.le.tc16(
+; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; AES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; AES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; AES-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; AES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i64 [[INDEXER_EXT]]
+; AES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %and.crc.data = and i8 %xor.crc.data, 1
+  %data.next = lshr i16 %data, 1
+  %check.sb = icmp eq i8 %and.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 29
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
+; NOAES-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; NOAES-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; NOAES-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; NOAES-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOAES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; AES-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; AES-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; AES-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; AES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; AES-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  %msg.ext = zext i8 %msg to i16
+  %msg.shl = shl nuw i16 %msg.ext, 8
+  %crc.init = xor i16 %msg.shl, %checksum
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp slt i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
+; NOAES-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; NOAES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOAES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; AES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; AES-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp slt i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
+; NOAES-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; NOAES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOAES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; AES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; AES-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp sge i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
+; NOAES-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; NOAES-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[OUTER_LOOP:.*]]
+; NOAES:       [[OUTER_LOOP]]:
+; NOAES-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; NOAES-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; NOAES-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; NOAES-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; NOAES:       [[PH]]:
+; NOAES-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; NOAES-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; NOAES-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; NOAES-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; NOAES-NEXT:    br label %[[INNER_LOOP:.*]]
+; NOAES:       [[INNER_LOOP]]:
+; NOAES-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOAES-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; NOAES:       [[INNER_EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; NOAES-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; NOAES-NEXT:    br label %[[OUTER_LOOP]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; NOAES-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+; AES-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; AES-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[OUTER_LOOP:.*]]
+; AES:       [[OUTER_LOOP]]:
+; AES-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; AES-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; AES-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; AES-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; AES:       [[PH]]:
+; AES-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; AES-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; AES-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; AES-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; AES-NEXT:    br label %[[INNER_LOOP:.*]]
+; AES:       [[INNER_LOOP]]:
+; AES-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
+; AES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.1, i64 [[INDEXER_EXT]]
+; AES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; AES-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; AES:       [[INNER_EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; AES-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; AES-NEXT:    br label %[[OUTER_LOOP]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; AES-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+entry:
+  br label %outer.loop
+
+outer.loop:                                        ; preds = %inner.exit, %entry
+  %crc.outer = phi i8 [ 0, %entry ], [ %crc.next, %inner.exit ]
+  %outer.iv = phi i32 [ 0, %entry ], [ %outer.iv.next, %inner.exit ]
+  %outer.exit.cond = icmp ult i32 %outer.iv, %loop.limit
+  br i1 %outer.exit.cond, label %ph, label %exit
+
+ph:                                                ; preds = %outer.loop
+  %outer.iv.ext = sext i32 %outer.iv to i64
+  %msg.outer.iv = getelementptr inbounds i8, ptr %msg, i64 %outer.iv.ext
+  %msg.load = load i8, ptr %msg.outer.iv, align 1
+  %crc.init = xor i8 %msg.load, %crc.outer
+  br label %inner.loop
+
+inner.loop:                                        ; preds = %inner.loop, %ph
+  %inner.iv = phi i32 [ 0, %ph ], [ %inner.iv.next, %inner.loop ]
+  %crc = phi i8 [ %crc.init, %ph ], [ %crc.next, %inner.loop ]
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %check.sb = icmp slt i8 %crc, 0
+  %crc.next = select i1 %check.sb, i8 %crc.xor, i8 %crc.shl
+  %inner.iv.next = add nuw nsw i32 %inner.iv, 1
+  %exit.cond = icmp samesign ult i32 %inner.iv, 7
+  br i1 %exit.cond, label %inner.loop, label %inner.exit
+
+inner.exit:                                        ; preds = %inner.loop
+  %outer.iv.next = add i32 %outer.iv, 1
+  br label %outer.loop
+
+exit:                                              ; preds = %outer.loop
+  ret i8 %crc.outer
+}
+
+define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
+; NOAES-LABEL: define i32 @crc32.le.tc8.data32(
+; NOAES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; NOAES-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
+; NOAES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i32 @crc32.le.tc8.data32(
+; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; AES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; AES-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; AES-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
+; AES-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
+; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i64 [[ENTRY3]], 8
+; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i64 [[ENTRY_LE_SHIFT]] to i32
+; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = xor i32 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i32 %crc.next
+}
+
+define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
+; ALL-LABEL: define i32 @crc.disabled.optsize(
+; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i32 %crc.next
+}
+
+define i32 @not.crc.unrelated.computation(i32 %checksum, i32 %msg) {
+; ALL-LABEL: define i32 @not.crc.unrelated.computation(
+; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0:[0-9]+]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[UNRELATED:%.*]] = phi i32 [ 1, %[[ENTRY]] ], [ [[UNRELATED_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL-NEXT:    [[UNRELATED_NEXT]] = shl i32 [[UNRELATED]], 2
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[UNRELATED_NEXT_LCSSA:%.*]] = phi i32 [ [[UNRELATED_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[RET:%.*]] = and i32 [[UNRELATED_NEXT_LCSSA]], [[CRC_NEXT_LCSSA]]
+; ALL-NEXT:    ret i32 [[RET]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %unrelated = phi i32 [ 1, %entry ], [ %unrelated.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %unrelated.next = shl i32 %unrelated, 2
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  %ret = and i32 %unrelated.next, %crc.next
+  ret i32 %ret
+}
+
+define i16 @not.crc.data.next.outside.user(i16 %crc.init, i16 %data.init) {
+; ALL-LABEL: define i16 @not.crc.data.next.outside.user(
+; ALL-SAME: i16 [[CRC_INIT:%.*]], i16 [[DATA_INIT:%.*]]) #[[ATTR0]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i16 [ [[DATA_INIT]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[DATA]], [[CRC]]
+; ALL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 3
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[XOR_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
+; ALL-NEXT:    [[DATA_NEXT]] = shl i16 [[DATA]], 1
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA_NEXT_LCSSA:%.*]] = phi i16 [ [[DATA_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[RET:%.*]] = xor i16 [[DATA_NEXT_LCSSA]], [[CRC_NEXT_LCSSA]]
+; ALL-NEXT:    ret i16 [[RET]]
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %data.init, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %data, %crc
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 3
+  %check.sb = icmp slt i16 %xor.crc.data, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %data.next = shl i16 %data, 1
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:
+  %ret = xor i16 %data.next, %crc.next
+  ret i16 %ret
+}
+;.
+; NOAES: attributes #[[ATTR0]] = { "target-features"="-aes" }
+; NOAES: attributes #[[ATTR1]] = { optsize "target-features"="-aes" }
+;.
+; AES: attributes #[[ATTR0]] = { "target-features"="+aes" }
+; AES: attributes #[[ATTR1]] = { optsize "target-features"="+aes" }
+; AES: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+;.
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
new file mode 100644
index 0000000000000..9412e534d984b
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -0,0 +1,1105 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
+; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,ALL32,NOZBC,NOZBC32 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ALL32,ZBC,ZBC32 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,ALL64,NOZBC,NOZBC64 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ALL64,ZBC,ZBC64 %s
+
+;.
+; NOZBC32: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOZBC32: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOZBC32: @.crctable.2 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOZBC32: @.crctable.3 = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
+; NOZBC32: @.crctable.4 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC32: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC32: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC32: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOZBC32: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+;.
+; ZBC32: @.crctable = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
+; ZBC32: @.crctable.1 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; ZBC32: @.crctable.2 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+;.
+; NOZBC64: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOZBC64: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOZBC64: @.crctable.2 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOZBC64: @.crctable.3 = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
+; NOZBC64: @.crctable.4 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC64: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC64: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC64: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOZBC64: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+;.
+; ZBC64: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; ZBC64: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; ZBC64: @.crctable.2 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; ZBC64: @.crctable.3 = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
+; ZBC64: @.crctable.4 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; ZBC64: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; ZBC64: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; ZBC64: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+;.
+define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
+; NOZBC32-LABEL: define i16 @crc16.le.tc8(
+; NOZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.le.tc8(
+; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; ZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; ZBC32-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ALL64-LABEL: define i16 @crc16.le.tc8(
+; ALL64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    br label %[[LOOP:.*]]
+; ALL64:       [[LOOP]]:
+; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; ALL64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ALL64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %and.data.crc = and i8 %xor.data.crc, 1
+  %data.next = lshr i8 %data, 1
+  %check.sb = icmp eq i8 %and.data.crc, 0
+  %crc.lshr = lshr i16 %crc, 1
+  %xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
+; NOZBC32-LABEL: define i16 @crc16.le.tc8.udiv(
+; NOZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.le.tc8.udiv(
+; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; ZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; ZBC32-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ALL64-LABEL: define i16 @crc16.le.tc8.udiv(
+; ALL64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    br label %[[LOOP:.*]]
+; ALL64:       [[LOOP]]:
+; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; ALL64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ALL64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %and.data.crc = and i8 %xor.data.crc, 1
+  %data.next = udiv i8 %data, 2
+  %check.sb = icmp eq i8 %and.data.crc, 0
+  %crc.lshr = udiv i16 %crc, 2
+  %xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
+; NOZBC32-LABEL: define i16 @crc16.le.tc16(
+; NOZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.le.tc16(
+; ZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; ZBC32-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ALL64-LABEL: define i16 @crc16.le.tc16(
+; ALL64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    br label %[[LOOP:.*]]
+; ALL64:       [[LOOP]]:
+; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ALL64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; ALL64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ALL64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %and.crc.data = and i16 %xor.crc.data, 1
+  %data.next = lshr i16 %data, 1
+  %check.sb = icmp eq i16 %and.crc.data, 0
+  %crc.lshr = lshr i16 %crc, 1
+  %crc.xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
+; NOZBC32-LABEL: define i8 @crc8.le.tc16(
+; NOZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i8 @crc8.le.tc16(
+; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; ZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i32 [[INDEXER_EXT]]
+; ZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ALL64-LABEL: define i8 @crc8.le.tc16(
+; ALL64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    br label %[[LOOP:.*]]
+; ALL64:       [[LOOP]]:
+; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ALL64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; ALL64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ALL64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; ALL64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %and.crc.data = and i8 %xor.crc.data, 1
+  %data.next = lshr i16 %data, 1
+  %check.sb = icmp eq i8 %and.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 29
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
+; NOZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; NOZBC32-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; NOZBC32-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; NOZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; ZBC32-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; ZBC32-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; ZBC32-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; ALL64-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; ALL64-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; ALL64-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; ALL64-NEXT:    br label %[[LOOP:.*]]
+; ALL64:       [[LOOP]]:
+; ALL64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ALL64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ALL64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  %msg.ext = zext i8 %msg to i16
+  %msg.shl = shl nuw i16 %msg.ext, 8
+  %crc.init = xor i16 %msg.shl, %checksum
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp slt i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
+; NOZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; NOZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; ZBC32-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; ALL64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    br label %[[LOOP:.*]]
+; ALL64:       [[LOOP]]:
+; ALL64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ALL64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ALL64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp slt i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
+; NOZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; NOZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; ZBC32-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; ALL64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    br label %[[LOOP:.*]]
+; ALL64:       [[LOOP]]:
+; ALL64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ALL64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ALL64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ALL64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp sge i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
+; NOZBC32-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; NOZBC32-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[OUTER_LOOP:.*]]
+; NOZBC32:       [[OUTER_LOOP]]:
+; NOZBC32-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; NOZBC32-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; NOZBC32-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; NOZBC32-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; NOZBC32:       [[PH]]:
+; NOZBC32-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; NOZBC32-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; NOZBC32-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; NOZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; NOZBC32-NEXT:    br label %[[INNER_LOOP:.*]]
+; NOZBC32:       [[INNER_LOOP]]:
+; NOZBC32-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC32-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; NOZBC32:       [[INNER_EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; NOZBC32-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; NOZBC32-NEXT:    br label %[[OUTER_LOOP]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; NOZBC32-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+; ZBC32-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; ZBC32-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[OUTER_LOOP:.*]]
+; ZBC32:       [[OUTER_LOOP]]:
+; ZBC32-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; ZBC32-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; ZBC32-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; ZBC32-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; ZBC32:       [[PH]]:
+; ZBC32-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; ZBC32-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; ZBC32-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; ZBC32-NEXT:    br label %[[INNER_LOOP:.*]]
+; ZBC32:       [[INNER_LOOP]]:
+; ZBC32-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i32
+; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.1, i32 [[INDEXER_EXT]]
+; ZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ZBC32-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; ZBC32:       [[INNER_EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; ZBC32-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; ZBC32-NEXT:    br label %[[OUTER_LOOP]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; ZBC32-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+; ALL64-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; ALL64-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; ALL64-NEXT:  [[ENTRY:.*]]:
+; ALL64-NEXT:    br label %[[OUTER_LOOP:.*]]
+; ALL64:       [[OUTER_LOOP]]:
+; ALL64-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; ALL64-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; ALL64-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; ALL64-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; ALL64:       [[PH]]:
+; ALL64-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; ALL64-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; ALL64-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; ALL64-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; ALL64-NEXT:    br label %[[INNER_LOOP:.*]]
+; ALL64:       [[INNER_LOOP]]:
+; ALL64-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; ALL64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
+; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i64 [[INDEXER_EXT]]
+; ALL64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ALL64-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; ALL64:       [[INNER_EXIT]]:
+; ALL64-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; ALL64-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; ALL64-NEXT:    br label %[[OUTER_LOOP]]
+; ALL64:       [[EXIT]]:
+; ALL64-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; ALL64-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+entry:
+  br label %outer.loop
+
+outer.loop:                                        ; preds = %inner.exit, %entry
+  %crc.outer = phi i8 [ 0, %entry ], [ %crc.next, %inner.exit ]
+  %outer.iv = phi i32 [ 0, %entry ], [ %outer.iv.next, %inner.exit ]
+  %outer.exit.cond = icmp ult i32 %outer.iv, %loop.limit
+  br i1 %outer.exit.cond, label %ph, label %exit
+
+ph:                                                ; preds = %outer.loop
+  %outer.iv.ext = sext i32 %outer.iv to i64
+  %msg.outer.iv = getelementptr inbounds i8, ptr %msg, i64 %outer.iv.ext
+  %msg.load = load i8, ptr %msg.outer.iv, align 1
+  %crc.init = xor i8 %msg.load, %crc.outer
+  br label %inner.loop
+
+inner.loop:                                        ; preds = %inner.loop, %ph
+  %inner.iv = phi i32 [ 0, %ph ], [ %inner.iv.next, %inner.loop ]
+  %crc = phi i8 [ %crc.init, %ph ], [ %crc.next, %inner.loop ]
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %check.sb = icmp slt i8 %crc, 0
+  %crc.next = select i1 %check.sb, i8 %crc.xor, i8 %crc.shl
+  %inner.iv.next = add nuw nsw i32 %inner.iv, 1
+  %exit.cond = icmp samesign ult i32 %inner.iv, 7
+  br i1 %exit.cond, label %inner.loop, label %inner.exit
+
+inner.exit:                                        ; preds = %inner.loop
+  %outer.iv.next = add i32 %outer.iv, 1
+  br label %outer.loop
+
+exit:                                              ; preds = %outer.loop
+  ret i8 %crc.outer
+}
+
+define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
+; NOZBC32-LABEL: define i32 @crc32.le.tc8.data32(
+; NOZBC32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; NOZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
+; NOZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i32 @crc32.le.tc8.data32(
+; ZBC32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.2, i32 [[INDEXER_EXT]]
+; ZBC32-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
+; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; NOZBC64-LABEL: define i32 @crc32.le.tc8.data32(
+; NOZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; NOZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
+; NOZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i32 @crc32.le.tc8.data32(
+; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; ZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; ZBC64-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
+; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
+; ZBC64-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
+; ZBC64-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i64 [[ENTRY3]], 8
+; ZBC64-NEXT:    [[ENTRY_CAST:%.*]] = trunc i64 [[ENTRY_LE_SHIFT]] to i32
+; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT4]] = xor i32 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i32 %crc.next
+}
+
+define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
+; ALL-LABEL: define i32 @crc.disabled.optsize(
+; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i32 %crc.next
+}
+
+define i32 @not.crc.unrelated.computation(i32 %checksum, i32 %msg) {
+; ALL-LABEL: define i32 @not.crc.unrelated.computation(
+; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0:[0-9]+]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[UNRELATED:%.*]] = phi i32 [ 1, %[[ENTRY]] ], [ [[UNRELATED_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL-NEXT:    [[UNRELATED_NEXT]] = shl i32 [[UNRELATED]], 2
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[UNRELATED_NEXT_LCSSA:%.*]] = phi i32 [ [[UNRELATED_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[RET:%.*]] = and i32 [[UNRELATED_NEXT_LCSSA]], [[CRC_NEXT_LCSSA]]
+; ALL-NEXT:    ret i32 [[RET]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %unrelated = phi i32 [ 1, %entry ], [ %unrelated.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %unrelated.next = shl i32 %unrelated, 2
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  %ret = and i32 %unrelated.next, %crc.next
+  ret i32 %ret
+}
+
+define i16 @not.crc.data.next.outside.user(i16 %crc.init, i16 %data.init) {
+; ALL-LABEL: define i16 @not.crc.data.next.outside.user(
+; ALL-SAME: i16 [[CRC_INIT:%.*]], i16 [[DATA_INIT:%.*]]) #[[ATTR0]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i16 [ [[DATA_INIT]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[DATA]], [[CRC]]
+; ALL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 3
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[XOR_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
+; ALL-NEXT:    [[DATA_NEXT]] = shl i16 [[DATA]], 1
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA_NEXT_LCSSA:%.*]] = phi i16 [ [[DATA_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[RET:%.*]] = xor i16 [[DATA_NEXT_LCSSA]], [[CRC_NEXT_LCSSA]]
+; ALL-NEXT:    ret i16 [[RET]]
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %data.init, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %data, %crc
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 3
+  %check.sb = icmp slt i16 %xor.crc.data, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %data.next = shl i16 %data, 1
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:
+  %ret = xor i16 %data.next, %crc.next
+  ret i16 %ret
+}
+;.
+; NOZBC32: attributes #[[ATTR0]] = { "target-features"="-zbc" }
+; NOZBC32: attributes #[[ATTR1]] = { optsize "target-features"="-zbc" }
+;.
+; ZBC32: attributes #[[ATTR0]] = { "target-features"="+zbc" }
+; ZBC32: attributes #[[ATTR1]] = { optsize "target-features"="+zbc" }
+; ZBC32: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+;.
+; NOZBC64: attributes #[[ATTR0]] = { "target-features"="-zbc" }
+; NOZBC64: attributes #[[ATTR1]] = { optsize "target-features"="-zbc" }
+;.
+; ZBC64: attributes #[[ATTR0]] = { "target-features"="+zbc" }
+; ZBC64: attributes #[[ATTR1]] = { optsize "target-features"="+zbc" }
+; ZBC64: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+;.
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; ALL32: {{.*}}
+; NOZBC: {{.*}}
+; ZBC: {{.*}}
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
new file mode 100644
index 0000000000000..a86de0f4240e6
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -0,0 +1,836 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
+; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mattr=-pclmul -S %s | FileCheck --check-prefixes=ALL,NOPCLMUL %s
+; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mattr=+pclmul -S %s | FileCheck --check-prefixes=ALL,PCLMUL %s
+
+;.
+; NOPCLMUL: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOPCLMUL: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOPCLMUL: @.crctable.2 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
+; NOPCLMUL: @.crctable.3 = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
+; NOPCLMUL: @.crctable.4 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOPCLMUL: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOPCLMUL: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOPCLMUL: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOPCLMUL: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+;.
+define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
+; NOPCLMUL-LABEL: define i16 @crc16.le.tc8(
+; NOPCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOPCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.le.tc8(
+; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; PCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %and.data.crc = and i8 %xor.data.crc, 1
+  %data.next = lshr i8 %data, 1
+  %check.sb = icmp eq i8 %and.data.crc, 0
+  %crc.lshr = lshr i16 %crc, 1
+  %xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
+; NOPCLMUL-LABEL: define i16 @crc16.le.tc8.udiv(
+; NOPCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOPCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.le.tc8.udiv(
+; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; PCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %and.data.crc = and i8 %xor.data.crc, 1
+  %data.next = udiv i8 %data, 2
+  %check.sb = icmp eq i8 %and.data.crc, 0
+  %crc.lshr = udiv i16 %crc, 2
+  %xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
+; NOPCLMUL-LABEL: define i16 @crc16.le.tc16(
+; NOPCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOPCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.le.tc16(
+; PCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; PCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; PCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
+; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
+; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
+; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %and.crc.data = and i16 %xor.crc.data, 1
+  %data.next = lshr i16 %data, 1
+  %check.sb = icmp eq i16 %and.crc.data, 0
+  %crc.lshr = lshr i16 %crc, 1
+  %crc.xor = xor i16 %crc.lshr, -24575
+  %crc.next = select i1 %check.sb, i16 %crc.lshr, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
+; NOPCLMUL-LABEL: define i8 @crc8.le.tc16(
+; NOPCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOPCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOPCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i8 @crc8.le.tc16(
+; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[ENTRY_CAST:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; PCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; PCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; PCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i16
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i16 @llvm.clmul.i16(i16 [[INDEXER_EXT]], i16 103)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i16 [[QUOT]], 255
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LE_MASK]], i16 58)
+; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i16 [[ENTRY3]], 8
+; PCLMUL-NEXT:    [[ENTRY_CAST]] = trunc i16 [[ENTRY_LE_SHIFT]] to i8
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[ENTRY_CAST]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %and.crc.data = and i8 %xor.crc.data, 1
+  %data.next = lshr i16 %data, 1
+  %check.sb = icmp eq i8 %and.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 29
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
+; NOPCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; NOPCLMUL-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; NOPCLMUL-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; NOPCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; PCLMUL-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; PCLMUL-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; PCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  %msg.ext = zext i8 %msg to i16
+  %msg.shl = shl nuw i16 %msg.ext, 8
+  %crc.init = xor i16 %msg.shl, %checksum
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp slt i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
+; NOPCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; NOPCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp slt i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
+; NOPCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; NOPCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
+; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
+; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
+; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %check.sb = icmp sge i16 %crc, 0
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
+; NOPCLMUL-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; NOPCLMUL-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[OUTER_LOOP:.*]]
+; NOPCLMUL:       [[OUTER_LOOP]]:
+; NOPCLMUL-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; NOPCLMUL-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; NOPCLMUL-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; NOPCLMUL-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[PH]]:
+; NOPCLMUL-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; NOPCLMUL-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; NOPCLMUL-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; NOPCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; NOPCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
+; NOPCLMUL:       [[INNER_LOOP]]:
+; NOPCLMUL-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOPCLMUL-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; NOPCLMUL:       [[INNER_EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; NOPCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; NOPCLMUL-NEXT:    br label %[[OUTER_LOOP]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; NOPCLMUL-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+; PCLMUL-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; PCLMUL-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[OUTER_LOOP:.*]]
+; PCLMUL:       [[OUTER_LOOP]]:
+; PCLMUL-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; PCLMUL-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; PCLMUL-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; PCLMUL-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; PCLMUL:       [[PH]]:
+; PCLMUL-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; PCLMUL-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; PCLMUL-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; PCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; PCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
+; PCLMUL:       [[INNER_LOOP]]:
+; PCLMUL-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[ENTRY_CAST:%.*]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i16
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i16 @llvm.clmul.i16(i16 [[INDEXER_EXT]], i16 284)
+; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i16 [[QUOT]], 8
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_SHIFT]], i16 285)
+; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i16 [[ENTRY3]], 255
+; PCLMUL-NEXT:    [[ENTRY_CAST]] = trunc i16 [[ENTRY_BE_MASK]] to i8
+; PCLMUL-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; PCLMUL:       [[INNER_EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[ENTRY_CAST]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; PCLMUL-NEXT:    br label %[[OUTER_LOOP]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; PCLMUL-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+entry:
+  br label %outer.loop
+
+outer.loop:                                        ; preds = %inner.exit, %entry
+  %crc.outer = phi i8 [ 0, %entry ], [ %crc.next, %inner.exit ]
+  %outer.iv = phi i32 [ 0, %entry ], [ %outer.iv.next, %inner.exit ]
+  %outer.exit.cond = icmp ult i32 %outer.iv, %loop.limit
+  br i1 %outer.exit.cond, label %ph, label %exit
+
+ph:                                                ; preds = %outer.loop
+  %outer.iv.ext = sext i32 %outer.iv to i64
+  %msg.outer.iv = getelementptr inbounds i8, ptr %msg, i64 %outer.iv.ext
+  %msg.load = load i8, ptr %msg.outer.iv, align 1
+  %crc.init = xor i8 %msg.load, %crc.outer
+  br label %inner.loop
+
+inner.loop:                                        ; preds = %inner.loop, %ph
+  %inner.iv = phi i32 [ 0, %ph ], [ %inner.iv.next, %inner.loop ]
+  %crc = phi i8 [ %crc.init, %ph ], [ %crc.next, %inner.loop ]
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %check.sb = icmp slt i8 %crc, 0
+  %crc.next = select i1 %check.sb, i8 %crc.xor, i8 %crc.shl
+  %inner.iv.next = add nuw nsw i32 %inner.iv, 1
+  %exit.cond = icmp samesign ult i32 %inner.iv, 7
+  br i1 %exit.cond, label %inner.loop, label %inner.exit
+
+inner.exit:                                        ; preds = %inner.loop
+  %outer.iv.next = add i32 %outer.iv, 1
+  br label %outer.loop
+
+exit:                                              ; preds = %outer.loop
+  ret i8 %crc.outer
+}
+
+define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
+; NOPCLMUL-LABEL: define i32 @crc32.le.tc8.data32(
+; NOPCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; NOPCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
+; NOPCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i32 @crc32.le.tc8.data32(
+; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; PCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; PCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; PCLMUL-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
+; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
+; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i64 [[ENTRY3]], 8
+; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i64 [[ENTRY_LE_SHIFT]] to i32
+; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i32 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i32 %crc.next
+}
+
+define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
+; ALL-LABEL: define i32 @crc.disabled.optsize(
+; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i32 %crc.next
+}
+
+define i32 @not.crc.unrelated.computation(i32 %checksum, i32 %msg) {
+; ALL-LABEL: define i32 @not.crc.unrelated.computation(
+; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0:[0-9]+]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[UNRELATED:%.*]] = phi i32 [ 1, %[[ENTRY]] ], [ [[UNRELATED_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL-NEXT:    [[UNRELATED_NEXT]] = shl i32 [[UNRELATED]], 2
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[UNRELATED_NEXT_LCSSA:%.*]] = phi i32 [ [[UNRELATED_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[RET:%.*]] = and i32 [[UNRELATED_NEXT_LCSSA]], [[CRC_NEXT_LCSSA]]
+; ALL-NEXT:    ret i32 [[RET]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %unrelated = phi i32 [ 1, %entry ], [ %unrelated.next, %loop ]
+  %xor.crc.data = xor i32 %crc, %data
+  %sb.crc.data = and i32 %xor.crc.data, 1
+  %check.sb = icmp eq i32 %sb.crc.data, 0
+  %crc.lshr = lshr i32 %crc, 1
+  %crc.xor = xor i32 %crc.lshr, 33800
+  %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %unrelated.next = shl i32 %unrelated, 2
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  %ret = and i32 %unrelated.next, %crc.next
+  ret i32 %ret
+}
+
+define i16 @not.crc.data.next.outside.user(i16 %crc.init, i16 %data.init) {
+; ALL-LABEL: define i16 @not.crc.data.next.outside.user(
+; ALL-SAME: i16 [[CRC_INIT:%.*]], i16 [[DATA_INIT:%.*]]) #[[ATTR0]] {
+; ALL-NEXT:  [[ENTRY:.*]]:
+; ALL-NEXT:    br label %[[LOOP:.*]]
+; ALL:       [[LOOP]]:
+; ALL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA:%.*]] = phi i16 [ [[DATA_INIT]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[DATA]], [[CRC]]
+; ALL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 3
+; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[XOR_CRC_DATA]], 0
+; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
+; ALL-NEXT:    [[DATA_NEXT]] = shl i16 [[DATA]], 1
+; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL:       [[EXIT]]:
+; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[DATA_NEXT_LCSSA:%.*]] = phi i16 [ [[DATA_NEXT]], %[[LOOP]] ]
+; ALL-NEXT:    [[RET:%.*]] = xor i16 [[DATA_NEXT_LCSSA]], [[CRC_NEXT_LCSSA]]
+; ALL-NEXT:    ret i16 [[RET]]
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %crc.init, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %data.init, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %data, %crc
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 3
+  %check.sb = icmp slt i16 %xor.crc.data, 0
+  %crc.next = select i1 %check.sb, i16 %crc.xor, i16 %crc.shl
+  %data.next = shl i16 %data, 1
+  %iv.next = add nuw nsw i32 %iv, 1
+  %exit.cond = icmp samesign ult i32 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:
+  %ret = xor i16 %data.next, %crc.next
+  ret i16 %ret
+}
+;.
+; NOPCLMUL: attributes #[[ATTR0]] = { "target-features"="-pclmul" }
+; NOPCLMUL: attributes #[[ATTR1]] = { optsize "target-features"="-pclmul" }
+;.
+; PCLMUL: attributes #[[ATTR0]] = { "target-features"="+pclmul" }
+; PCLMUL: attributes #[[ATTR1]] = { optsize "target-features"="+pclmul" }
+; PCLMUL: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+;.

>From f4f42dbd85ddcb116f4694fc584df90b4ea5274f Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Fri, 12 Jun 2026 14:12:46 -0500
Subject: [PATCH 03/18] Apply requested changes

---
 llvm/lib/Analysis/HashRecognize.cpp           |   6 +
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 220 ++++++++----------
 .../AArch64/cyclic-redundancy-check.ll        |  47 ++--
 .../RISCV/cyclic-redundancy-check.ll          |  47 ++--
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  |  62 +++--
 5 files changed, 181 insertions(+), 201 deletions(-)

diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index 623571636a9fa..40d838a4092f9 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -413,7 +413,13 @@ CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
   APInt G = GenPoly.reverseBits().zext(DivBW);
   G.setBit(BW);
   APInt Mu = calculateGF2Quotient(Dividend, G);
+  // Only the low byte of the reciprocal is useful in LE because it will get
+  // multiplied by another byte and then immediately masked by 0xFF.
   C.Reciprocal = Mu.trunc(BW + 1).reverseBits().zext(ClmulBW).getLoBits(8);
+  // shl(1) here enables an optimization where two shifts then XOR can be
+  // replaced with an XOR then one shift. Normally one of the shifts would be by
+  // 7 and the other by 8, but by shifting here the shift by 7 becomes another
+  // shift by 8.
   C.Generator = GenPoly.zext(ClmulBW).shl(1);
   return C;
 }
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 02a7bbb8d752a..ccfe8fb23088b 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -202,8 +202,6 @@ class LoopIdiomRecognize {
 private:
   using StoreList = SmallVector<StoreInst *, 8>;
   using StoreListMap = MapVector<Value *, StoreList>;
-  using CRCTableFn =
-      function_ref<Value *(IRBuilderBase &Builder, Value *Indexer)>;
 
   StoreListMap StoreRefsForMemset;
   StoreListMap StoreRefsForMemsetPattern;
@@ -261,9 +259,6 @@ class LoopIdiomRecognize {
   bool avoidLIRForMultiBlockLoop(bool IsMemset = false,
                                  bool IsLoopMemset = false);
   bool optimizeCRCLoop(const PolynomialInfo &Info);
-  bool optimizeCRCLoopWithFastClmul(const PolynomialInfo &Info);
-  void buildReducedCRCLoop(const PolynomialInfo &Info,
-                           CRCTableFn GetTableEntry);
 
   /// @}
   /// \name Noncountable Loop Idiom Handling
@@ -1565,105 +1560,6 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
   if (TT.getArch() == Triple::hexagon)
     return false;
 
-  // If using llvm.clmul would be more efficient, use that instead of a lookup
-  // table.
-  if (optimizeCRCLoopWithFastClmul(Info))
-    return true;
-
-  // First, create a new GlobalVariable corresponding to the
-  // Sarwate-lookup-table.
-  Type *CRCTy = Info.LHS->getType();
-  std::array<Constant *, 256> CRCConstants;
-  transform(HashRecognize::genSarwateTable(Info.RHS, Info.IsBigEndian),
-            CRCConstants.begin(),
-            [CRCTy](const APInt &E) { return ConstantInt::get(CRCTy, E); });
-  Constant *ConstArray =
-      ConstantArray::get(ArrayType::get(CRCTy, 256), CRCConstants);
-  GlobalVariable *GV =
-      new GlobalVariable(M, ConstArray->getType(), true,
-                         GlobalValue::PrivateLinkage, ConstArray, ".crctable");
-
-  // Build a reduced per-byte loop which loads an entry from the Sarwate lookup
-  // table each iteration.
-  //
-  // Little-endian:
-  //   crc = (crc >> 8) ^ tbl[(iv'th byte of data) ^ (bottom byte of crc)]
-  // Big-Endian:
-  //   crc = (crc << 8) ^ tbl[(iv'th byte of data) ^ (top byte of crc)]
-  buildReducedCRCLoop(Info, [&](auto &Builder, Value *Indexer) {
-    // Always index into a GEP using the index type.
-    Indexer = Builder.CreateZExt(
-        Indexer, SE->getDataLayout().getIndexType(GV->getType()),
-        "indexer.ext");
-
-    // CRCTableLd = CRCTable[(iv'th byte of data) ^ (top|bottom) byte of CRC].
-    Value *CRCTableGEP =
-        Builder.CreateInBoundsGEP(CRCTy, GV, Indexer, "tbl.ptradd");
-    Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP, "tbl.ld");
-
-    return CRCTableLd;
-  });
-
-  return true;
-}
-
-bool LoopIdiomRecognize::optimizeCRCLoopWithFastClmul(
-    const PolynomialInfo &Info) {
-  Type *CRCTy = Info.LHS->getType();
-  unsigned CRCBW = CRCTy->getIntegerBitWidth();
-  Type *ClmulTy = IntegerType::get(CRCTy->getContext(), 2 * CRCBW);
-
-  // Only apply this optimization strategy if llvm.clmul would lower into a
-  // native instruction.
-  if (!TTI->haveFastClmul(ClmulTy))
-    return false;
-
-  // First, generate the two constants required for a Barrett-style reduction.
-  CRCBarrettConstants Constants =
-      HashRecognize::genBarrettConstants(Info.RHS, Info.ByteOrderSwapped);
-  Value *Reciprocal = ConstantInt::get(ClmulTy, Constants.Reciprocal);
-  Value *Generator = ConstantInt::get(ClmulTy, Constants.Generator);
-
-  // Build a reduced per-byte loop which computes the lookup table entry on the
-  // fly each iteration using a Barrett-style reduction.
-  //
-  // Little-endian:
-  //   q = ((iv'th byte of data) ^ (bottom byte of crc)) clmul (reciprocal term)
-  //   entry = (bottom byte of q) clmul (generator term)
-  //   crc = (crc >> 8) ^ (top byte of entry)
-  // Big-Endian:
-  //   q = ((iv'th byte of data) ^ (top byte of crc)) clmul (reciprocal term)
-  //   entry = (top byte of q) clmul (generator term)
-  //   crc = (crc << 8) ^ (bottom byte of entry)
-  buildReducedCRCLoop(Info, [&](auto &Builder, Value *Indexer) {
-    // Approximate floor(Indexer / (generator term)) using Indexer * (reciprocal
-    // term).
-    Indexer = Builder.CreateZExt(Indexer, ClmulTy, "indexer.ext");
-    Value *Quotient = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, Indexer,
-                                                    Reciprocal, {}, "quot");
-    Quotient = Info.ByteOrderSwapped
-                   ? Builder.CreateLShr(Quotient, CRCBW, "quot.be.shift")
-                   : Builder.CreateAnd(Quotient, 0xFF, "quot.le.mask");
-
-    // floor(Indexer / (generator term)) * (generator term) should give us what
-    // the Sarwate table entry would be.
-    Value *Entry = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, Quotient,
-                                                 Generator, {}, "entry");
-    Entry =
-        Info.ByteOrderSwapped
-            ? Builder.CreateAnd(Entry, APInt::getLowBitsSet(2 * CRCBW, CRCBW),
-                                "entry.be.mask")
-            : Builder.CreateLShr(Entry, 8, "entry.le.shift");
-    Entry = Builder.CreateTrunc(Entry, CRCTy, "entry.cast");
-
-    return Entry;
-  });
-
-  return true;
-}
-
-void LoopIdiomRecognize::buildReducedCRCLoop(
-    const PolynomialInfo &Info, LoopIdiomRecognize::CRCTableFn GetTableEntry) {
   Type *CRCTy = Info.LHS->getType();
   unsigned CRCBW = CRCTy->getIntegerBitWidth();
 
@@ -1697,8 +1593,8 @@ void LoopIdiomRecognize::buildReducedCRCLoop(
     deleteDeadInstruction(ExitCond);
   }
 
-  // Finally, fill the loop with the Sarwate-table-lookup logic, and replace all
-  // uses of ComputedValue.
+  // Finally, fill the loop with the logic to compute 8 bits at a time, and
+  // replace all uses of ComputedValue.
   {
     auto LoByte = [](IRBuilderBase &Builder, Value *Op, const Twine &Name) {
       return Builder.CreateZExtOrTrunc(
@@ -1752,18 +1648,105 @@ void LoopIdiomRecognize::buildReducedCRCLoop(
     Indexer = Info.IsBigEndian ? HiIdx(Builder, Indexer, "indexer.hi")
                                : LoByte(Builder, Indexer, "indexer.lo");
 
-    // Get the Sarwate lookup table entry corresponding to Indexer. This could
-    // either be a load or an on-the-fly computation, so let the caller decide.
-    Value *CRCTableEntry = GetTableEntry(Builder, Indexer);
-
-    // CRCNext = (CRC (<<|>>) 8) ^ CRCTableLd, or simply CRCTableLd in case of
-    // CRC-8.
-    Value *CRCNext = CRCTableEntry;
-    if (CRCBW > 8) {
-      Value *CRCShift = Info.IsBigEndian
-                            ? Builder.CreateShl(CRC, 8, "crc.be.shift")
-                            : Builder.CreateLShr(CRC, 8, "crc.le.shift");
-      CRCNext = Builder.CreateXor(CRCShift, CRCTableEntry, "crc.next");
+    // Compute the next value of the CRC register based on Indexer. This could
+    // either be a table load or an on-the-fly computation, depending on whether
+    // llvm.clmul is fast on the target.
+    Value *CRCNext;
+    Type *ClmulTy = IntegerType::get(CRCTy->getContext(), 2 * CRCBW);
+    if (TTI->haveFastClmul(ClmulTy)) {
+      // Use a Barrett-style reduction to calculate CRCNext with two clmuls.
+      // Little-endian:
+      //   q = ((iv'th byte of data) ^ (bottom byte of crc)) clmul (reciprocal)
+      //   entry = (bottom byte of q) clmul (genpoly)
+      //   crc = (crc >> 8) ^ (entry >> 7)
+      //   Equivalently, to save one shift instruction:
+      //   (genBarrettConstants gives us genpoly << 1)
+      //   entry = (bottom byte of q) clmul (genpoly << 1)
+      //   crc = (crc ^ entry) >> 8
+      // Big-Endian:
+      //   q = ((iv'th byte of data) ^ (top byte of crc)) clmul (reciprocal)
+      //   entry = (top byte of q) clmul (genpoly)
+      //   crc = (crc << 8) ^ (bottom CRCBW bits of entry)
+
+      // First, generate the two constants required for a Barrett-style
+      // reduction.
+      CRCBarrettConstants Constants =
+          HashRecognize::genBarrettConstants(Info.RHS, Info.IsBigEndian);
+      Value *Reciprocal = ConstantInt::get(ClmulTy, Constants.Reciprocal);
+      Value *Generator = ConstantInt::get(ClmulTy, Constants.Generator);
+
+      // Approximate floor(Indexer / GenPoly) using Indexer * Reciprocal.
+      Indexer = Builder.CreateZExt(Indexer, ClmulTy, "indexer.ext");
+      Value *Quotient = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, Indexer,
+                                                      Reciprocal, {}, "quot");
+      Quotient = Info.IsBigEndian
+                     ? Builder.CreateLShr(Quotient, CRCBW, "quot.be.shift")
+                     : Builder.CreateAnd(Quotient, 0xFF, "quot.le.mask");
+
+      // floor(Indexer / GenPoly) * GenPoly should give us the equivalent of the
+      // Sarwate table entry.
+      Value *ComputedByte = Builder.CreateBinaryIntrinsic(
+          Intrinsic::clmul, Quotient, Generator, {}, "entry");
+      if (Info.IsBigEndian) {
+        // Keep the low bits of the clmul.
+        ComputedByte = Builder.CreateTrunc(ComputedByte, CRCTy, "entry.lo");
+        // CRCNext = (CRC << 8) ^ ComputedByte, or simply ComputedByte in case
+        // of CRC-8.
+        CRCNext = ComputedByte;
+        if (CRCBW > 8) {
+          Value *CRCShift = Builder.CreateShl(CRC, 8, "crc.be.shift");
+          CRCNext = Builder.CreateXor(CRCShift, ComputedByte, "crc.next");
+        }
+      } else {
+        // CRCNext = (CRC ^ ComputedByte) >> 8, or simply ComputedByte >> 8 in
+        // case of CRC-8.
+        Value *CRCNextPreshift = ComputedByte;
+        if (CRCBW > 8) {
+          Value *CRCWide = Builder.CreateZExt(CRC, ClmulTy, "crc.wide");
+          CRCNextPreshift =
+              Builder.CreateXor(CRCWide, ComputedByte, "crc.wide.xor");
+        }
+        CRCNext = Builder.CreateLShr(CRCNextPreshift, 8, "crc.next.wide");
+        CRCNext = Builder.CreateTrunc(CRCNext, CRCTy, "crc.next");
+      }
+    } else {
+      // Use the Sarwate algorithm to calculate CRCNext with one lookup table
+      // load. Little-endian:
+      //   crc = (crc >> 8) ^ tbl[(iv'th byte of data) ^ (bottom byte of crc)]
+      // Big-Endian:
+      //   crc = (crc << 8) ^ tbl[(iv'th byte of data) ^ (top byte of crc)]
+
+      // First, create a new GlobalVariable corresponding to the
+      // Sarwate-lookup-table.
+      std::array<Constant *, 256> CRCConstants;
+      transform(HashRecognize::genSarwateTable(Info.RHS, Info.IsBigEndian),
+                CRCConstants.begin(),
+                [CRCTy](const APInt &E) { return ConstantInt::get(CRCTy, E); });
+      Constant *ConstArray =
+          ConstantArray::get(ArrayType::get(CRCTy, 256), CRCConstants);
+      GlobalVariable *GV = new GlobalVariable(M, ConstArray->getType(), true,
+                                              GlobalValue::PrivateLinkage,
+                                              ConstArray, ".crctable");
+
+      // Always index into a GEP using the index type.
+      Indexer = Builder.CreateZExt(
+          Indexer, SE->getDataLayout().getIndexType(GV->getType()),
+          "indexer.ext");
+
+      // CRCTableLd = CRCTable[(iv'th byte of data) ^ (top|bottom) byte of CRC].
+      Value *CRCTableGEP =
+          Builder.CreateInBoundsGEP(CRCTy, GV, Indexer, "tbl.ptradd");
+      Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP, "tbl.ld");
+
+      // CRCNext = (CRC (<<|>>) 8) ^ CRCTableLd, or simply CRCTableLd in case of
+      // CRC-8.
+      CRCNext = CRCTableLd;
+      if (CRCBW > 8) {
+        Value *CRCShift = Info.IsBigEndian
+                              ? Builder.CreateShl(CRC, 8, "crc.be.shift")
+                              : Builder.CreateLShr(CRC, 8, "crc.le.shift");
+        CRCNext = Builder.CreateXor(CRCShift, CRCTableLd, "crc.next");
+      }
     }
 
     // Connect the back-edge for the loop, and RAUW the ComputedValue.
@@ -1778,6 +1761,7 @@ void LoopIdiomRecognize::buildReducedCRCLoop(
       RecursivelyDeleteDeadPHINode(PN);
     SE->forgetLoop(CurLoop);
   }
+  return true;
 }
 
 bool LoopIdiomRecognize::runOnNoncountableLoop() {
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index cbda266771fd3..f7fc1ec631fe9 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -55,10 +55,10 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -128,10 +128,10 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -203,10 +203,10 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
 ; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -347,10 +347,9 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; AES-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; AES-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -414,10 +413,9 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; AES-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; AES-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -478,10 +476,9 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; AES-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; AES-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -648,10 +645,10 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; AES-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
 ; AES-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
-; AES-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i64 [[ENTRY3]], 8
-; AES-NEXT:    [[ENTRY_CAST:%.*]] = trunc i64 [[ENTRY_LE_SHIFT]] to i32
-; AES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i32 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i32 [[CRC2]] to i64
+; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i64 [[CRC_WIDE]], [[ENTRY3]]
+; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i64 [[CRC_WIDE_XOR]], 8
+; AES-NEXT:    [[CRC_NEXT4]] = trunc i64 [[CRC_NEXT_WIDE]] to i32
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 9412e534d984b..93b9352d65282 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -77,10 +77,10 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; ZBC32-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; ZBC32-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; ZBC32-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -173,10 +173,10 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; ZBC32-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; ZBC32-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; ZBC32-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -271,10 +271,10 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; ZBC32-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; ZBC32-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; ZBC32-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; ZBC32-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
 ; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -462,10 +462,9 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; ZBC32-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; ZBC32-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -553,10 +552,9 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; ZBC32-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; ZBC32-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -638,10 +636,9 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; ZBC32-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; ZBC32-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; ZBC32-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -909,10 +906,10 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC64-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
 ; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
 ; ZBC64-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
-; ZBC64-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i64 [[ENTRY3]], 8
-; ZBC64-NEXT:    [[ENTRY_CAST:%.*]] = trunc i64 [[ENTRY_LE_SHIFT]] to i32
-; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT4]] = xor i32 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; ZBC64-NEXT:    [[CRC_WIDE:%.*]] = zext i32 [[CRC2]] to i64
+; ZBC64-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i64 [[CRC_WIDE]], [[ENTRY3]]
+; ZBC64-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i64 [[CRC_WIDE_XOR]], 8
+; ZBC64-NEXT:    [[CRC_NEXT4]] = trunc i64 [[CRC_NEXT_WIDE]] to i32
 ; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index a86de0f4240e6..866dd238e7630 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -52,10 +52,10 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -125,10 +125,10 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -200,10 +200,10 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i32 [[ENTRY3]], 8
-; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_LE_SHIFT]] to i16
-; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
+; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
+; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -263,7 +263,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[ENTRY_CAST:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
 ; PCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
 ; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
@@ -274,13 +274,13 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i16 @llvm.clmul.i16(i16 [[INDEXER_EXT]], i16 103)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i16 [[QUOT]], 255
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LE_MASK]], i16 58)
-; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i16 [[ENTRY3]], 8
-; PCLMUL-NEXT:    [[ENTRY_CAST]] = trunc i16 [[ENTRY_LE_SHIFT]] to i8
+; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i16 [[ENTRY3]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i16 [[CRC_NEXT_WIDE]] to i8
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[ENTRY_CAST]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT4]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -347,10 +347,9 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; PCLMUL-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -414,10 +413,9 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; PCLMUL-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -478,10 +476,9 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
 ; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i32 [[ENTRY3]], 65535
-; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i32 [[ENTRY_BE_MASK]] to i16
+; PCLMUL-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
 ; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
@@ -557,18 +554,17 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; PCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
 ; PCLMUL:       [[INNER_LOOP]]:
 ; PCLMUL-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[ENTRY_CAST:%.*]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[ENTRY_LO:%.*]], %[[INNER_LOOP]] ]
 ; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i16
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i16 @llvm.clmul.i16(i16 [[INDEXER_EXT]], i16 284)
 ; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i16 [[QUOT]], 8
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_SHIFT]], i16 285)
-; PCLMUL-NEXT:    [[ENTRY_BE_MASK:%.*]] = and i16 [[ENTRY3]], 255
-; PCLMUL-NEXT:    [[ENTRY_CAST]] = trunc i16 [[ENTRY_BE_MASK]] to i8
+; PCLMUL-NEXT:    [[ENTRY_LO]] = trunc i16 [[ENTRY3]] to i8
 ; PCLMUL-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; PCLMUL:       [[INNER_EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[ENTRY_CAST]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[ENTRY_LO]], %[[INNER_LOOP]] ]
 ; PCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; PCLMUL-NEXT:    br label %[[OUTER_LOOP]]
 ; PCLMUL:       [[EXIT]]:
@@ -651,10 +647,10 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; PCLMUL-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
 ; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
-; PCLMUL-NEXT:    [[ENTRY_LE_SHIFT:%.*]] = lshr i64 [[ENTRY3]], 8
-; PCLMUL-NEXT:    [[ENTRY_CAST:%.*]] = trunc i64 [[ENTRY_LE_SHIFT]] to i32
-; PCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i32 [[CRC_LE_SHIFT]], [[ENTRY_CAST]]
+; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i32 [[CRC2]] to i64
+; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i64 [[CRC_WIDE]], [[ENTRY3]]
+; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i64 [[CRC_WIDE_XOR]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i64 [[CRC_NEXT_WIDE]] to i32
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
 ; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
 ; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]

>From a038538dac27d31c86c4f53c9be69775c48654a3 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Wed, 24 Jun 2026 11:59:26 -0500
Subject: [PATCH 04/18] Rework computation to remove loop entirely

---
 llvm/include/llvm/Analysis/HashRecognize.h    |  26 +-
 llvm/lib/Analysis/HashRecognize.cpp           | 103 +++--
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 267 +++++++-----
 .../HashRecognize/cyclic-redundancy-check.ll  |  18 +-
 .../AArch64/cyclic-redundancy-check.ll        | 354 +++++++++-------
 .../RISCV/cyclic-redundancy-check.ll          | 382 +++++++++++-------
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  | 376 ++++++++++-------
 7 files changed, 923 insertions(+), 603 deletions(-)

diff --git a/llvm/include/llvm/Analysis/HashRecognize.h b/llvm/include/llvm/Analysis/HashRecognize.h
index edd7059725409..a8c62d3f9d11d 100644
--- a/llvm/include/llvm/Analysis/HashRecognize.h
+++ b/llvm/include/llvm/Analysis/HashRecognize.h
@@ -35,15 +35,20 @@ struct CRCTable : public std::array<APInt, 256> {
 #endif
 };
 
-/// The constants used to perform polynomial division with a Barrett-style
-/// reduction into two polynomial multiplications instead.
+/// The constants used to perform a Polynomial (GF(2)) Barrett Reduction as
+/// roughly specified in Intel's Fast CRC Computation white paper
+/// (https://www.researchgate.net/publication/263424619_Fast_CRC_computation).
+/// Both constants are bit-reflected across their respective widths for
+/// bit-reflected CRCs.
 struct CRCBarrettConstants {
-  // An approximation of the polynomial quotient floor(x^2w / P(x)), where P(x)
-  // is the generating polynomial and w is the CRC width.
-  APInt Reciprocal;
+  // The constant used in the first clmul operation, which is mu =
+  // floor(x^(CRCBW+DataBW) / P(x)). Bit width is DataBW+1.
+  APInt Mu;
 
-  // The generating polynomial P(x) in full, adjusted for endianness.
-  APInt Generator;
+  // The constant used in the second clmul operation, which is the generating
+  // polynomial P(x) with the implied x^CRCBW term included. Bit width is
+  // CRCBW+1.
+  APInt FullGenPoly;
 
   LLVM_ABI void print(raw_ostream &OS) const;
 
@@ -105,10 +110,11 @@ class HashRecognize {
   LLVM_ABI static CRCTable genSarwateTable(const APInt &GenPoly,
                                            bool IsBigEndian);
 
-  // Auxilary entry point after analysis to generate constants for a
-  // Barrett-style reduction.
+  // Auxilary entry point after analysis to generate constants for a GF(2)
+  // Barrett Reduction.
   LLVM_ABI static CRCBarrettConstants
-  genBarrettConstants(const APInt &GenPoly, bool ByteOrderSwapped);
+  genBarrettConstants(const APInt &GenPoly, unsigned DataBW,
+                      bool ByteOrderSwapped);
 
   LLVM_ABI void print(raw_ostream &OS) const;
 
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index 40d838a4092f9..44ae6eceb3167 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -376,52 +376,80 @@ CRCTable HashRecognize::genSarwateTable(const APInt &GenPoly,
   return Table;
 }
 
-// Divide one GF(2) polynomial by another.
-static APInt calculateGF2Quotient(APInt Dividend, const APInt &Divisor) {
-  unsigned DivisorDeg = Divisor.getActiveBits() - 1;
-  APInt Quotient = APInt::getZero(Dividend.getBitWidth());
+// Perform polynomial (GF(2)) floor division. This is based on the
+// floor_division(S, P) algorithm in
+// https://www.corsix.org/content/barrett-reduction-polynomials. Note that the
+// maximum degree of the returned polynomial is max(0, deg(Dividend) -
+// deg(Divisor)), but the bit width will be the same as that of Dividend.
+static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
+  assert(!Divisor.isZero() && "Cannot divide by zero");
+
+  // Extend the divisor bit width to match the dividend.
+  Divisor = Divisor.zext(Dividend.getBitWidth());
+
+  // The Poly argument should never be zero, or else this underflows.
+  auto Deg = [](const APInt &Poly) { return Poly.getActiveBits() - 1; };
+
+  // Calculate deg(Divisor) once since it never changes.
+  unsigned DivisorDeg = Deg(Divisor);
+  // Only calculate deg(Dividend) after Dividend is known to be nonzero.
   unsigned DividendDeg;
-  while (!Dividend.isZero() &&
-         (DividendDeg = Dividend.getActiveBits() - 1) >= DivisorDeg) {
+
+  // Q = 0
+  APInt Quotient = APInt::getZero(Dividend.getBitWidth());
+  // S != 0 and deg(S) >= deg(P)
+  while (!Dividend.isZero() && (DividendDeg = Deg(Dividend)) >= DivisorDeg) {
+    // T = S[deg(S)] / P[deg(P)]
     unsigned Shift = DividendDeg - DivisorDeg;
+    // Q = Q + T
     Quotient.setBit(Shift);
+    // S = S - T * P
     Dividend ^= Divisor.shl(Shift);
   }
   return Quotient;
 }
 
-// Generate constants (mu/reciprocal, P/generator) for a Barrett-style
-// reduction. This reduction allows the Sarwate table entry to be computed on
-// the fly, rather than requiring a load from memory (on supporting hardware).
+// Generate the constants for performing a Polynomial (GF(2)) Barrett Reduction
+// according to Intel's Fast CRC Computation white paper
+// (https://www.researchgate.net/publication/263424619_Fast_CRC_computation),
+// with some adjustments to account for the fact that CRCBW and DataBW can vary.
 CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
-                                                       bool ByteOrderSwapped) {
-  unsigned BW = GenPoly.getBitWidth();
-  unsigned ClmulBW = BW * 2;
-  unsigned DivBW = ClmulBW + 1;
-  APInt Dividend = APInt::getSignedMinValue(DivBW);
-  CRCBarrettConstants C;
-
-  if (ByteOrderSwapped) {
-    APInt G = GenPoly.zext(DivBW);
-    G.setBit(BW);
-    APInt Mu = calculateGF2Quotient(Dividend, G);
-    C.Reciprocal = Mu.trunc(ClmulBW);
-    C.Generator = G.trunc(ClmulBW);
-    return C;
+                                                       unsigned DataBW,
+                                                       bool IsBigEndian) {
+  unsigned CRCBW = GenPoly.getBitWidth();
+
+  // Recover the full generating polynomial in normal form by reflecting the LE
+  // case and adding the implied x^CRCBW term.
+  APInt FullGenPoly = IsBigEndian ? GenPoly : GenPoly.reverseBits();
+  // deg(P(x)) = CRCBW due to the implied term, and thus P(x) must fit in
+  // exactly CRCBW+1 bits.
+  FullGenPoly = FullGenPoly.zext(CRCBW + 1);
+  FullGenPoly.setBit(CRCBW);
+
+  // Calculate mu = floor(x^(CRCBW+DataBW) / P(x)).
+  unsigned DivBW = CRCBW + DataBW + 1;
+  APInt Mu =
+      floorDivideGF2(APInt::getOneBitSet(DivBW, CRCBW + DataBW), FullGenPoly);
+  // deg(mu) <= deg(x^(CRCBW+DataBW)) - deg(P(x)) = CRCBW+DataBW - CRCBW =
+  // DataBW, and thus mu must fit in at most DataBW+1 bits.
+  Mu = Mu.trunc(DataBW + 1);
+
+  // In the bit-reflected case, mu and P(x) must be bit-reflected across their
+  // respective widths for the corresponding Barrett reduction steps.
+  if (!IsBigEndian) {
+    Mu = Mu.reverseBits();
+    FullGenPoly = FullGenPoly.reverseBits();
   }
 
-  APInt G = GenPoly.reverseBits().zext(DivBW);
-  G.setBit(BW);
-  APInt Mu = calculateGF2Quotient(Dividend, G);
-  // Only the low byte of the reciprocal is useful in LE because it will get
-  // multiplied by another byte and then immediately masked by 0xFF.
-  C.Reciprocal = Mu.trunc(BW + 1).reverseBits().zext(ClmulBW).getLoBits(8);
-  // shl(1) here enables an optimization where two shifts then XOR can be
-  // replaced with an XOR then one shift. Normally one of the shifts would be by
-  // 7 and the other by 8, but by shifting here the shift by 7 becomes another
-  // shift by 8.
-  C.Generator = GenPoly.zext(ClmulBW).shl(1);
-  return C;
+  // The width used for clmul operations should be a power of 2, and should be
+  // at least CRCBW + DataBW.
+  unsigned ClmulBW = 2 * std::max(CRCBW, DataBW);
+
+  // Finally, cast mu/mu' and P(x)/P(x)' to the width used for clmul operations.
+  CRCBarrettConstants Constants;
+  Constants.Mu = Mu.zext(ClmulBW);
+  Constants.FullGenPoly = FullGenPoly.zext(ClmulBW);
+  return Constants;
 }
 
 /// Checks that \p P1 and \p P2 are used together in an XOR in the use-def chain
@@ -580,7 +608,7 @@ void CRCTable::dump() const { print(dbgs()); }
 #endif
 
 void CRCBarrettConstants::print(raw_ostream &OS) const {
-  OS << "Reciprocal = " << Reciprocal << ", Generator = " << Generator << '\n';
+  OS << "Reciprocal = " << Mu << ", Generator = " << FullGenPoly << '\n';
 }
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -622,7 +650,8 @@ void HashRecognize::print(raw_ostream &OS) const {
   OS.indent(2) << "Computed CRC lookup table:\n";
   genSarwateTable(Info.RHS, Info.IsBigEndian).print(OS);
   OS.indent(2) << "Computed CRC Barrett constants:\n";
-  genBarrettConstants(Info.RHS, Info.IsBigEndian).print(OS);
+  genBarrettConstants(Info.RHS, Info.TripCount, Info.IsBigEndian)
+      .print(OS);
 }
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index ccfe8fb23088b..a4ad4e83ca3ca 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -258,7 +258,8 @@ class LoopIdiomRecognize {
                                   const SCEV *BECount);
   bool avoidLIRForMultiBlockLoop(bool IsMemset = false,
                                  bool IsLoopMemset = false);
-  bool optimizeCRCLoop(const PolynomialInfo &Info);
+  bool optimizeCRCLoopToClmul(const PolynomialInfo &Info);
+  bool optimizeCRCLoopToLookup(const PolynomialInfo &Info);
 
   /// @}
   /// \name Noncountable Loop Idiom Handling
@@ -397,11 +398,12 @@ bool LoopIdiomRecognize::runOnCountableLoop() {
     MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
   }
 
-  // Optimize a CRC loop if HashRecognize found one, provided we're not
-  // optimizing for size.
-  if (!DisableLIRP::HashRecognize && !ApplyCodeSizeHeuristics)
+  // Optimize a CRC loop if HashRecognize found one, but don't generate a lookup
+  // table if we're optimizing for size.
+  if (!DisableLIRP::HashRecognize)
     if (auto Res = HashRecognize(*CurLoop, *SE).getResult())
-      optimizeCRCLoop(*Res);
+      MadeChange |= optimizeCRCLoopToClmul(*Res) ||
+                    (!ApplyCodeSizeHeuristics && optimizeCRCLoopToLookup(*Res));
 
   return MadeChange;
 }
@@ -1549,7 +1551,121 @@ bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
   return false;
 }
 
-bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
+bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
+  Type *CRCTy = Info.LHS->getType();
+  unsigned CRCBW = CRCTy->getIntegerBitWidth();
+  // The TripCount determines how many bits of data are processed, regardless of
+  // whether the actual data bit width matches (if auxiliary data is even used
+  // at all).
+  unsigned EffectiveDataBW = Info.TripCount;
+  // The width used for clmul operations should be a power of 2, and should be
+  // at least CRCBW + DataBW.
+  unsigned ClmulBW = 2 * std::max(CRCBW, EffectiveDataBW);
+  Type *ClmulTy = IntegerType::get(CRCTy->getContext(), ClmulBW);
+
+  // This optimization should not be applied if there is no fast clmul operation
+  // for the required width on the target.
+  // TODO: If EffectiveDataBW > CRCBW, then the data could probably be split
+  // into multiple chunks and processed in a loop.
+  if (!TTI->haveFastClmul(ClmulTy))
+    return false;
+
+  // First, generate the constants required for GF(2) Barrett reduction.
+  CRCBarrettConstants Constants = HashRecognize::genBarrettConstants(
+      Info.RHS, EffectiveDataBW, Info.IsBigEndian);
+  Value *Mu = ConstantInt::get(ClmulTy, Constants.Mu.zext(ClmulBW));
+  Value *FullGenPoly =
+      ConstantInt::get(ClmulTy, Constants.FullGenPoly.zext(ClmulBW));
+
+  IRBuilder<> Builder(CurLoop->getLoopPreheader()->getTerminator());
+
+  Value *CRCExt = Builder.CreateZExt(Info.LHS, ClmulTy, "crc.ext");
+
+  // For the big-endian case, align the leftmost bit of the CRC with the
+  // leftmost bit of the data. For the little-endian case, align the rightmost
+  // bits (nothing to do).
+  Value *CRCAlignData = CRCExt;
+  if (Info.IsBigEndian) {
+    if (CRCBW > EffectiveDataBW)
+      CRCAlignData = Builder.CreateLShr(CRCAlignData, CRCBW - EffectiveDataBW,
+                                        "crc.be.lshr");
+    else if (EffectiveDataBW > CRCBW)
+      CRCAlignData = Builder.CreateShl(CRCAlignData, EffectiveDataBW - CRCBW,
+                                       "crc.be.shl");
+  }
+
+  // If auxiliary data is present, XOR it in with the CRC.
+  Value *ClmulMuInput = CRCAlignData;
+  if (Value *Data = Info.LHSAux) {
+    unsigned ActualDataBW = Data->getType()->getIntegerBitWidth();
+    if (ActualDataBW > EffectiveDataBW) {
+      // Extract the useful bits of the data and discard the rest.
+      Data = Info.IsBigEndian
+                 ? Builder.CreateLShr(Data, ActualDataBW - EffectiveDataBW,
+                                      "data.be.lshr")
+                 : Builder.CreateAnd(
+                       Data,
+                       ConstantInt::get(
+                           Data->getType(),
+                           APInt::getLowBitsSet(ActualDataBW, EffectiveDataBW)),
+                       "data.le.mask");
+    }
+    // This isn't necessarily a zext-- ActualDataBW could be greater than
+    // ClmulBW.
+    Value *DataExt = Builder.CreateZExtOrTrunc(Data, ClmulTy, "data.ext");
+    // For the big-endian case, ensure the data is aligned properly.
+    if (Info.IsBigEndian && EffectiveDataBW > ActualDataBW) {
+      DataExt = Builder.CreateShl(DataExt, EffectiveDataBW - ActualDataBW,
+                                  "data.be.shl");
+    }
+
+    ClmulMuInput = Builder.CreateXor(CRCAlignData, DataExt, "xor.crc.data");
+  }
+
+  // Perform the first clmul operation with the mu/mu' constant. Input is DataBW
+  // bits and Mu is DataBW+1 bits, so the result will be 2*DataBW bits.
+  Value *ClmulMu = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulMuInput,
+                                                 Mu, {}, "clmul.mu");
+
+  // Extract the relevant DataBW bits from the result.
+  Value *ClmulGPInput =
+      Info.IsBigEndian
+          ? Builder.CreateLShr(ClmulMu, EffectiveDataBW, "quot.be.lshr")
+          : Builder.CreateAnd(
+                ClmulMu,
+                ConstantInt::get(
+                    ClmulTy, APInt::getLowBitsSet(ClmulBW, EffectiveDataBW)),
+                "quot.le.mask");
+
+  // Perform the second clmul operation with the P(x)/P(x)' constant. Input is
+  // DataBW bits and GP is CRCBW+1 bits, so the result will be CRCBW+DataBW
+  // bits.
+  Value *ClmulGP = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulGPInput,
+                                                 FullGenPoly, {}, "clmul.gp");
+
+  // For the big-endian case, align the leftmost bit of the CRC with the
+  // leftmost bit of the clmul result. For the little-endian case, align the
+  // rightmost bits (nothing to do).
+  Value *CRCAlignClmul = CRCExt;
+  if (Info.IsBigEndian) {
+    CRCAlignClmul = Builder.CreateShl(CRCExt, EffectiveDataBW, "crc.be.shl");
+  }
+  // Get the remainder by subtracting (XORing) the calculated multiple of
+  // GenPoly from the CRC.
+  Value *CRCNext = Builder.CreateXor(CRCAlignClmul, ClmulGP, "xor.crc.mult");
+  // For the little-endian case, the leftmost bits of the XOR are relevant.
+  if (!Info.IsBigEndian) {
+    CRCNext = Builder.CreateLShr(CRCNext, EffectiveDataBW, "crc.le.lshr");
+  }
+  CRCNext = Builder.CreateTrunc(CRCNext, CRCTy, "crc.next");
+
+  // Replace the result of the loop with the new computed CRC value.
+  Info.ComputedValue->replaceUsesOutsideBlock(CRCNext, CurLoop->getLoopLatch());
+
+  return true;
+}
+
+bool LoopIdiomRecognize::optimizeCRCLoopToLookup(const PolynomialInfo &Info) {
   // FIXME: Hexagon has a special HexagonLoopIdiom that optimizes CRC using
   // carry-less multiplication instructions, which is more efficient than our
   // Sarwate table-lookup optimization. Hence, until we're able to emit
@@ -1560,13 +1676,24 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
   if (TT.getArch() == Triple::hexagon)
     return false;
 
+  // First, create a new GlobalVariable corresponding to the
+  // Sarwate-lookup-table.
   Type *CRCTy = Info.LHS->getType();
   unsigned CRCBW = CRCTy->getIntegerBitWidth();
+  std::array<Constant *, 256> CRCConstants;
+  transform(HashRecognize::genSarwateTable(Info.RHS, Info.IsBigEndian),
+            CRCConstants.begin(),
+            [CRCTy](const APInt &E) { return ConstantInt::get(CRCTy, E); });
+  Constant *ConstArray =
+      ConstantArray::get(ArrayType::get(CRCTy, 256), CRCConstants);
+  GlobalVariable *GV =
+      new GlobalVariable(M, ConstArray->getType(), true,
+                         GlobalValue::PrivateLinkage, ConstArray, ".crctable");
 
   PHINode *IV = CurLoop->getCanonicalInductionVariable();
   SmallVector<PHINode *, 2> Cleanup;
 
-  // First, mark all PHIs for removal except IV.
+  // Next, mark all PHIs for removal except IV.
   {
     for (PHINode &PN : CurLoop->getHeader()->phis()) {
       if (&PN == IV)
@@ -1593,8 +1720,13 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
     deleteDeadInstruction(ExitCond);
   }
 
-  // Finally, fill the loop with the logic to compute 8 bits at a time, and
-  // replace all uses of ComputedValue.
+  // Finally, fill the loop with the Sarwate-table-lookup logic, and replace all
+  // uses of ComputedValue.
+  //
+  // Little-endian:
+  //   crc = (crc >> 8) ^ tbl[(iv'th byte of data) ^ (bottom byte of crc)]
+  // Big-Endian:
+  //   crc = (crc << 8) ^ tbl[(iv'th byte of data) ^ (top byte of crc)]
   {
     auto LoByte = [](IRBuilderBase &Builder, Value *Op, const Twine &Name) {
       return Builder.CreateZExtOrTrunc(
@@ -1648,105 +1780,24 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
     Indexer = Info.IsBigEndian ? HiIdx(Builder, Indexer, "indexer.hi")
                                : LoByte(Builder, Indexer, "indexer.lo");
 
-    // Compute the next value of the CRC register based on Indexer. This could
-    // either be a table load or an on-the-fly computation, depending on whether
-    // llvm.clmul is fast on the target.
-    Value *CRCNext;
-    Type *ClmulTy = IntegerType::get(CRCTy->getContext(), 2 * CRCBW);
-    if (TTI->haveFastClmul(ClmulTy)) {
-      // Use a Barrett-style reduction to calculate CRCNext with two clmuls.
-      // Little-endian:
-      //   q = ((iv'th byte of data) ^ (bottom byte of crc)) clmul (reciprocal)
-      //   entry = (bottom byte of q) clmul (genpoly)
-      //   crc = (crc >> 8) ^ (entry >> 7)
-      //   Equivalently, to save one shift instruction:
-      //   (genBarrettConstants gives us genpoly << 1)
-      //   entry = (bottom byte of q) clmul (genpoly << 1)
-      //   crc = (crc ^ entry) >> 8
-      // Big-Endian:
-      //   q = ((iv'th byte of data) ^ (top byte of crc)) clmul (reciprocal)
-      //   entry = (top byte of q) clmul (genpoly)
-      //   crc = (crc << 8) ^ (bottom CRCBW bits of entry)
-
-      // First, generate the two constants required for a Barrett-style
-      // reduction.
-      CRCBarrettConstants Constants =
-          HashRecognize::genBarrettConstants(Info.RHS, Info.IsBigEndian);
-      Value *Reciprocal = ConstantInt::get(ClmulTy, Constants.Reciprocal);
-      Value *Generator = ConstantInt::get(ClmulTy, Constants.Generator);
-
-      // Approximate floor(Indexer / GenPoly) using Indexer * Reciprocal.
-      Indexer = Builder.CreateZExt(Indexer, ClmulTy, "indexer.ext");
-      Value *Quotient = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, Indexer,
-                                                      Reciprocal, {}, "quot");
-      Quotient = Info.IsBigEndian
-                     ? Builder.CreateLShr(Quotient, CRCBW, "quot.be.shift")
-                     : Builder.CreateAnd(Quotient, 0xFF, "quot.le.mask");
-
-      // floor(Indexer / GenPoly) * GenPoly should give us the equivalent of the
-      // Sarwate table entry.
-      Value *ComputedByte = Builder.CreateBinaryIntrinsic(
-          Intrinsic::clmul, Quotient, Generator, {}, "entry");
-      if (Info.IsBigEndian) {
-        // Keep the low bits of the clmul.
-        ComputedByte = Builder.CreateTrunc(ComputedByte, CRCTy, "entry.lo");
-        // CRCNext = (CRC << 8) ^ ComputedByte, or simply ComputedByte in case
-        // of CRC-8.
-        CRCNext = ComputedByte;
-        if (CRCBW > 8) {
-          Value *CRCShift = Builder.CreateShl(CRC, 8, "crc.be.shift");
-          CRCNext = Builder.CreateXor(CRCShift, ComputedByte, "crc.next");
-        }
-      } else {
-        // CRCNext = (CRC ^ ComputedByte) >> 8, or simply ComputedByte >> 8 in
-        // case of CRC-8.
-        Value *CRCNextPreshift = ComputedByte;
-        if (CRCBW > 8) {
-          Value *CRCWide = Builder.CreateZExt(CRC, ClmulTy, "crc.wide");
-          CRCNextPreshift =
-              Builder.CreateXor(CRCWide, ComputedByte, "crc.wide.xor");
-        }
-        CRCNext = Builder.CreateLShr(CRCNextPreshift, 8, "crc.next.wide");
-        CRCNext = Builder.CreateTrunc(CRCNext, CRCTy, "crc.next");
-      }
-    } else {
-      // Use the Sarwate algorithm to calculate CRCNext with one lookup table
-      // load. Little-endian:
-      //   crc = (crc >> 8) ^ tbl[(iv'th byte of data) ^ (bottom byte of crc)]
-      // Big-Endian:
-      //   crc = (crc << 8) ^ tbl[(iv'th byte of data) ^ (top byte of crc)]
-
-      // First, create a new GlobalVariable corresponding to the
-      // Sarwate-lookup-table.
-      std::array<Constant *, 256> CRCConstants;
-      transform(HashRecognize::genSarwateTable(Info.RHS, Info.IsBigEndian),
-                CRCConstants.begin(),
-                [CRCTy](const APInt &E) { return ConstantInt::get(CRCTy, E); });
-      Constant *ConstArray =
-          ConstantArray::get(ArrayType::get(CRCTy, 256), CRCConstants);
-      GlobalVariable *GV = new GlobalVariable(M, ConstArray->getType(), true,
-                                              GlobalValue::PrivateLinkage,
-                                              ConstArray, ".crctable");
-
-      // Always index into a GEP using the index type.
-      Indexer = Builder.CreateZExt(
-          Indexer, SE->getDataLayout().getIndexType(GV->getType()),
-          "indexer.ext");
-
-      // CRCTableLd = CRCTable[(iv'th byte of data) ^ (top|bottom) byte of CRC].
-      Value *CRCTableGEP =
-          Builder.CreateInBoundsGEP(CRCTy, GV, Indexer, "tbl.ptradd");
-      Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP, "tbl.ld");
-
-      // CRCNext = (CRC (<<|>>) 8) ^ CRCTableLd, or simply CRCTableLd in case of
-      // CRC-8.
-      CRCNext = CRCTableLd;
-      if (CRCBW > 8) {
-        Value *CRCShift = Info.IsBigEndian
-                              ? Builder.CreateShl(CRC, 8, "crc.be.shift")
-                              : Builder.CreateLShr(CRC, 8, "crc.le.shift");
-        CRCNext = Builder.CreateXor(CRCShift, CRCTableLd, "crc.next");
-      }
+    // Always index into a GEP using the index type.
+    Indexer = Builder.CreateZExt(
+        Indexer, SE->getDataLayout().getIndexType(GV->getType()),
+        "indexer.ext");
+
+    // CRCTableLd = CRCTable[(iv'th byte of data) ^ (top|bottom) byte of CRC].
+    Value *CRCTableGEP =
+        Builder.CreateInBoundsGEP(CRCTy, GV, Indexer, "tbl.ptradd");
+    Value *CRCTableLd = Builder.CreateLoad(CRCTy, CRCTableGEP, "tbl.ld");
+
+    // CRCNext = (CRC (<<|>>) 8) ^ CRCTableLd, or simply CRCTableLd in case of
+    // CRC-8.
+    Value *CRCNext = CRCTableLd;
+    if (CRCBW > 8) {
+      Value *CRCShift = Info.IsBigEndian
+                            ? Builder.CreateShl(CRC, 8, "crc.be.shift")
+                            : Builder.CreateLShr(CRC, 8, "crc.le.shift");
+      CRCNext = Builder.CreateXor(CRCShift, CRCTableLd, "crc.next");
     }
 
     // Connect the back-edge for the loop, and RAUW the ComputedValue.
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index 8ea699852fe48..43b643f0ea8ba 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -26,7 +26,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 255, Generator = 81922
+; CHECK-NEXT:  Reciprocal = 511, Generator = 81923
 ;
 entry:
   br label %loop
@@ -76,7 +76,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 255, Generator = 81922
+; CHECK-NEXT:  Reciprocal = 511, Generator = 81923
 ;
 entry:
   br label %loop
@@ -126,7 +126,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 255, Generator = 81922
+; CHECK-NEXT:  Reciprocal = 114687, Generator = 81923
 ;
 entry:
   br label %loop
@@ -175,7 +175,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; CHECK-NEXT:  26 19 8 1 5 12 23 30 31 22 13 4 0 9 18 27
 ; CHECK-NEXT:  16 25 2 11 15 6 29 20 21 28 7 14 10 3 24 17
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 103, Generator = 58
+; CHECK-NEXT:  Reciprocal = 24423, Generator = 59
 ;
 entry:
   br label %loop
@@ -224,7 +224,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 69936, Generator = 69665
+; CHECK-NEXT:  Reciprocal = 273, Generator = 69665
 ;
 entry:
   %msg.ext = zext i8 %msg to i16
@@ -271,7 +271,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 69936, Generator = 69665
+; CHECK-NEXT:  Reciprocal = 273, Generator = 69665
 ;
 entry:
   br label %loop
@@ -315,7 +315,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 69936, Generator = 69665
+; CHECK-NEXT:  Reciprocal = 273, Generator = 69665
 ;
 entry:
   br label %loop
@@ -421,7 +421,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; CHECK-NEXT:  59150 63111 50204 54677 41258 45219 33336 37809 27462 31439 18516 23005 11618 15595 3696 8185
 ; CHECK-NEXT:  63375 58886 54429 50452 45483 40994 37561 33584 31687 27214 22741 18780 15843 11370 7921 3960
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 17, Generator = 67600
+; CHECK-NEXT:  Reciprocal = 273, Generator = 67601
 ;
 entry:
   br label %loop
@@ -470,7 +470,7 @@ define i16 @crc16.be.tc8.zext.data(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  57792 57538 58308 58054 58824 58570 59340 59086 59856 59602 60372 60118 60888 60634 61404 61150
 ; CHECK-NEXT:  61920 61666 62436 62182 62952 62698 63468 63214 63984 63730 64500 64246 65016 64762 65532 65278
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 65795, Generator = 65794
+; CHECK-NEXT:  Reciprocal = 257, Generator = 65794
 ;
 entry:
   br label %loop
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index f7fc1ec631fe9..e9513386d4b42 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -13,8 +13,7 @@
 ; NOAES: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOAES: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
-; AES: @.crctable = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
-; AES: @.crctable.1 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; AES: @.crctable = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOAES-LABEL: define i16 @crc16.le.tc8(
@@ -43,27 +42,33 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; AES-LABEL: define i16 @crc16.le.tc8(
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; AES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
-; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
+; AES-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
+; AES-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
+; AES-NEXT:    [[DATA_NEXT]] = lshr i8 [[DATA]], 1
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
+; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
+; AES-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -116,27 +121,33 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; AES-LABEL: define i16 @crc16.le.tc8.udiv(
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; AES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
-; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
+; AES-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
+; AES-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
+; AES-NEXT:    [[DATA_NEXT]] = udiv i8 [[DATA]], 2
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
+; AES-NEXT:    [[CRC_LSHR:%.*]] = udiv i16 [[CRC]], 2
+; AES-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -190,28 +201,32 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; AES-LABEL: define i16 @crc16.le.tc16(
 ; AES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 114687)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; AES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
-; AES-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
+; AES-NEXT:    [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
+; AES-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
+; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
+; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -263,24 +278,33 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; AES-LABEL: define i8 @crc8.le.tc16(
 ; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 24423)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 59)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; AES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; AES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
-; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; AES-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; AES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i64 [[INDEXER_EXT]]
-; AES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; AES-NEXT:    [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
+; AES-NEXT:    [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
+; AES-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
+; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
+; AES-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -337,24 +361,27 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; AES-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; AES-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; AES-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; AES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; AES-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -403,24 +430,27 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; AES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; AES-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -466,24 +496,27 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; AES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; AES-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; AES-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; AES-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; AES-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; AES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp sge i16 [[CRC]], 0
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -556,7 +589,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; AES-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
 ; AES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
 ; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
-; AES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.1, i64 [[INDEXER_EXT]]
+; AES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i64 [[INDEXER_EXT]]
 ; AES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
 ; AES-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
 ; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
@@ -632,28 +665,33 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; AES-LABEL: define i32 @crc32.le.tc8.data32(
 ; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
+; AES-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
 ; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; AES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
-; AES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
-; AES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
-; AES-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; AES-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
-; AES-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
-; AES-NEXT:    [[CRC_WIDE:%.*]] = zext i32 [[CRC2]] to i64
-; AES-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i64 [[CRC_WIDE]], [[ENTRY3]]
-; AES-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i64 [[CRC_WIDE_XOR]], 8
-; AES-NEXT:    [[CRC_NEXT4]] = trunc i64 [[CRC_NEXT_WIDE]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; AES-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; AES-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
 ; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -679,27 +717,59 @@ exit:                                              ; preds = %loop
 }
 
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
-; ALL-LABEL: define i32 @crc.disabled.optsize(
-; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
-; ALL-NEXT:  [[ENTRY:.*]]:
-; ALL-NEXT:    br label %[[LOOP:.*]]
-; ALL:       [[LOOP]]:
-; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL:       [[EXIT]]:
-; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
-; ALL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+; NOAES-LABEL: define i32 @crc.disabled.optsize(
+; NOAES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; NOAES-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; NOAES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; NOAES-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; NOAES-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; NOAES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; NOAES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; NOAES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i32 @crc.disabled.optsize(
+; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; AES-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; AES-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; AES-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 93b9352d65282..1744b4d6185ea 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -15,9 +15,8 @@
 ; NOZBC32: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOZBC32: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
-; ZBC32: @.crctable = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
-; ZBC32: @.crctable.1 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; ZBC32: @.crctable.2 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; ZBC32: @.crctable = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; ZBC32: @.crctable.1 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 ; NOZBC64: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
 ; NOZBC64: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
@@ -65,27 +64,33 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; ZBC32-LABEL: define i16 @crc16.le.tc8(
 ; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
+; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
 ; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; ZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
-; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; ZBC32-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; ZBC32-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; ZBC32-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
+; ZBC32-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
+; ZBC32-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
+; ZBC32-NEXT:    [[DATA_NEXT]] = lshr i8 [[DATA]], 1
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
+; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
+; ZBC32-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; ALL64-LABEL: define i16 @crc16.le.tc8(
@@ -161,27 +166,33 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; ZBC32-LABEL: define i16 @crc16.le.tc8.udiv(
 ; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
+; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
 ; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; ZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
-; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; ZBC32-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; ZBC32-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; ZBC32-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
+; ZBC32-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
+; ZBC32-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
+; ZBC32-NEXT:    [[DATA_NEXT]] = udiv i8 [[DATA]], 2
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
+; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = udiv i16 [[CRC]], 2
+; ZBC32-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; ALL64-LABEL: define i16 @crc16.le.tc8.udiv(
@@ -258,28 +269,32 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-LABEL: define i16 @crc16.le.tc16(
 ; ZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 114687)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
 ; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
-; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; ZBC32-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; ZBC32-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; ZBC32-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
+; ZBC32-NEXT:    [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
+; ZBC32-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
+; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
+; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; ALL64-LABEL: define i16 @crc16.le.tc16(
@@ -355,24 +370,33 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; ZBC32-LABEL: define i8 @crc8.le.tc16(
 ; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 24423)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 59)
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
 ; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; ZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
-; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i32 [[INDEXER_EXT]]
-; ZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
+; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
+; ZBC32-NEXT:    [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
+; ZBC32-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
+; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
+; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 ; ALL64-LABEL: define i8 @crc8.le.tc16(
@@ -452,24 +476,27 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; ZBC32-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; ZBC32-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
 ; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; ZBC32-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
@@ -542,24 +569,27 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
 ; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; ZBC32-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
@@ -626,24 +656,27 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
 ; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; ZBC32-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; ZBC32-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; ZBC32-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; ZBC32-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; ZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp sge i16 [[CRC]], 0
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
 ; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
@@ -737,7 +770,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; ZBC32-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
 ; ZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
 ; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i32
-; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.1, i32 [[INDEXER_EXT]]
+; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i32 [[INDEXER_EXT]]
 ; ZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
 ; ZBC32-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
 ; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
@@ -855,7 +888,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
 ; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
 ; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.2, i32 [[INDEXER_EXT]]
+; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.1, i32 [[INDEXER_EXT]]
 ; ZBC32-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
 ; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
 ; ZBC32-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
@@ -893,28 +926,33 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC64-LABEL: define i32 @crc32.le.tc8.data32(
 ; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
+; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
+; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
+; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
+; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
+; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
 ; ZBC64-NEXT:    br label %[[LOOP:.*]]
 ; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
 ; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
-; ZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; ZBC64-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
-; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
-; ZBC64-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
-; ZBC64-NEXT:    [[CRC_WIDE:%.*]] = zext i32 [[CRC2]] to i64
-; ZBC64-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i64 [[CRC_WIDE]], [[ENTRY3]]
-; ZBC64-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i64 [[CRC_WIDE_XOR]], 8
-; ZBC64-NEXT:    [[CRC_NEXT4]] = trunc i64 [[CRC_NEXT_WIDE]] to i32
+; ZBC64-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ZBC64-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ZBC64-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ZBC64-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ZBC64-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ZBC64-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
 ; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -940,27 +978,81 @@ exit:                                              ; preds = %loop
 }
 
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
-; ALL-LABEL: define i32 @crc.disabled.optsize(
-; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
-; ALL-NEXT:  [[ENTRY:.*]]:
-; ALL-NEXT:    br label %[[LOOP:.*]]
-; ALL:       [[LOOP]]:
-; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL:       [[EXIT]]:
-; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
-; ALL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+; ALL32-LABEL: define i32 @crc.disabled.optsize(
+; ALL32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; ALL32-NEXT:  [[ENTRY:.*]]:
+; ALL32-NEXT:    br label %[[LOOP:.*]]
+; ALL32:       [[LOOP]]:
+; ALL32-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL32-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL32-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL32-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL32-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL32-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ALL32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL32:       [[EXIT]]:
+; ALL32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; NOZBC-LABEL: define i32 @crc.disabled.optsize(
+; NOZBC-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; NOZBC-NEXT:  [[ENTRY:.*]]:
+; NOZBC-NEXT:    br label %[[LOOP:.*]]
+; NOZBC:       [[LOOP]]:
+; NOZBC-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; NOZBC-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; NOZBC-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; NOZBC-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; NOZBC-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; NOZBC-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; NOZBC-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; NOZBC-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; NOZBC-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC:       [[EXIT]]:
+; NOZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; NOZBC-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i32 @crc.disabled.optsize(
+; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
+; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
+; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
+; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
+; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
+; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ZBC64-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ZBC64-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ZBC64-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ZBC64-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ZBC64-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -1097,6 +1189,4 @@ exit:
 ; ZBC64: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; ALL32: {{.*}}
-; NOZBC: {{.*}}
 ; ZBC: {{.*}}
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index 866dd238e7630..4265e9573a0f8 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -40,27 +40,33 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; PCLMUL-LABEL: define i16 @crc16.le.tc8(
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; PCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
+; PCLMUL-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
+; PCLMUL-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
+; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i8 [[DATA]], 1
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
+; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
+; PCLMUL-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -113,27 +119,33 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; PCLMUL-LABEL: define i16 @crc16.le.tc8.udiv(
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; PCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i32
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
+; PCLMUL-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
+; PCLMUL-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
+; PCLMUL-NEXT:    [[DATA_NEXT]] = udiv i8 [[DATA]], 2
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
+; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = udiv i16 [[CRC]], 2
+; PCLMUL-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -187,28 +199,32 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-LABEL: define i16 @crc16.le.tc16(
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 114687)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; PCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
-; PCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 255)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[QUOT]], 255
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81922)
-; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i16 [[CRC2]] to i32
-; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i32 [[CRC_WIDE]], [[ENTRY3]]
-; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i32 [[CRC_WIDE_XOR]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i32 [[CRC_NEXT_WIDE]] to i16
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
+; PCLMUL-NEXT:    [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
+; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
+; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -260,27 +276,33 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-LABEL: define i8 @crc8.le.tc16(
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 24423)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 59)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; PCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; PCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
-; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; PCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i16
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i16 @llvm.clmul.i16(i16 [[INDEXER_EXT]], i16 103)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i16 [[QUOT]], 255
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LE_MASK]], i16 58)
-; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i16 [[ENTRY3]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i16 [[CRC_NEXT_WIDE]] to i8
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
+; PCLMUL-NEXT:    [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
+; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
+; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -337,24 +359,27 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; PCLMUL-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; PCLMUL-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; PCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; PCLMUL-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -403,24 +428,27 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; PCLMUL-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -466,24 +494,27 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
+; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i32 @llvm.clmul.i32(i32 [[INDEXER_EXT]], i32 69936)
-; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i32 [[QUOT]], 16
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_SHIFT]], i32 69665)
-; PCLMUL-NEXT:    [[ENTRY_LO:%.*]] = trunc i32 [[ENTRY3]] to i16
-; PCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = xor i16 [[CRC_BE_SHIFT]], [[ENTRY_LO]]
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp sge i16 [[CRC]], 0
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -551,20 +582,26 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; PCLMUL-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
 ; PCLMUL-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
 ; PCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CRC_INIT]] to i16
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_EXT]], i16 284)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; PCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
 ; PCLMUL:       [[INNER_LOOP]]:
 ; PCLMUL-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[ENTRY_LO:%.*]], %[[INNER_LOOP]] ]
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i16
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i16 @llvm.clmul.i16(i16 [[INDEXER_EXT]], i16 284)
-; PCLMUL-NEXT:    [[QUOT_BE_SHIFT:%.*]] = lshr i16 [[QUOT]], 8
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_SHIFT]], i16 285)
-; PCLMUL-NEXT:    [[ENTRY_LO]] = trunc i16 [[ENTRY3]] to i8
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[CRC_NEXT:%.*]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i8 [[CRC]], 0
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_XOR]], i8 [[CRC_SHL]]
 ; PCLMUL-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[INNER_IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; PCLMUL:       [[INNER_EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[ENTRY_LO]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; PCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; PCLMUL-NEXT:    br label %[[OUTER_LOOP]]
 ; PCLMUL:       [[EXIT]]:
@@ -634,28 +671,33 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; PCLMUL-LABEL: define i32 @crc32.le.tc8.data32(
 ; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT4:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; PCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
-; PCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
-; PCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
-; PCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
-; PCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; PCLMUL-NEXT:    [[QUOT:%.*]] = call i64 @llvm.clmul.i64(i64 [[INDEXER_EXT]], i64 17)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[QUOT]], 255
-; PCLMUL-NEXT:    [[ENTRY3:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67600)
-; PCLMUL-NEXT:    [[CRC_WIDE:%.*]] = zext i32 [[CRC2]] to i64
-; PCLMUL-NEXT:    [[CRC_WIDE_XOR:%.*]] = xor i64 [[CRC_WIDE]], [[ENTRY3]]
-; PCLMUL-NEXT:    [[CRC_NEXT_WIDE:%.*]] = lshr i64 [[CRC_WIDE_XOR]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT4]] = trunc i64 [[CRC_NEXT_WIDE]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; PCLMUL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
 ; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; PCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT4]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -681,27 +723,59 @@ exit:                                              ; preds = %loop
 }
 
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
-; ALL-LABEL: define i32 @crc.disabled.optsize(
-; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
-; ALL-NEXT:  [[ENTRY:.*]]:
-; ALL-NEXT:    br label %[[LOOP:.*]]
-; ALL:       [[LOOP]]:
-; ALL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; ALL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; ALL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; ALL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; ALL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; ALL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; ALL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; ALL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ALL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL:       [[EXIT]]:
-; ALL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
-; ALL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+; NOPCLMUL-LABEL: define i32 @crc.disabled.optsize(
+; NOPCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; NOPCLMUL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; NOPCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; NOPCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; NOPCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; NOPCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i32 @crc.disabled.optsize(
+; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; PCLMUL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop

>From d54959688f3622e7dee2120bb23782d106d20f3f Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Wed, 24 Jun 2026 16:53:06 -0500
Subject: [PATCH 05/18] Bail on edge case to avoid miscompile

---
 llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index a4ad4e83ca3ca..b7c8d3be2b4e1 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1563,6 +1563,16 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   unsigned ClmulBW = 2 * std::max(CRCBW, EffectiveDataBW);
   Type *ClmulTy = IntegerType::get(CRCTy->getContext(), ClmulBW);
 
+  // For big-endian CRC loops where the auxiliary data is XORed with the CRC
+  // inside the loop, the bits won't be aligned properly if the bit widths don't
+  // match, and thus the CRC computation is incorrect, but HashRecognize will
+  // still detect the loop. Since this optimization always produces a correct
+  // CRC computation, bail in this edge case.
+  if (Info.ByteOrderSwapped && Info.LHSAux &&
+      (EffectiveDataBW != CRCBW ||
+       Info.LHSAux->getType()->getIntegerBitWidth() != CRCBW))
+    return false;
+
   // This optimization should not be applied if there is no fast clmul operation
   // for the required width on the target.
   // TODO: If EffectiveDataBW > CRCBW, then the data could probably be split

>From 71742beb5322ed7693a9ee9c3784e97e1cf7457a Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Wed, 24 Jun 2026 17:46:29 -0500
Subject: [PATCH 06/18] Apply requested changes

---
 llvm/include/llvm/Analysis/HashRecognize.h    |  3 ++
 llvm/lib/Analysis/HashRecognize.cpp           | 26 ++++--------
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 41 +++++++++----------
 3 files changed, 31 insertions(+), 39 deletions(-)

diff --git a/llvm/include/llvm/Analysis/HashRecognize.h b/llvm/include/llvm/Analysis/HashRecognize.h
index a8c62d3f9d11d..0be563b284826 100644
--- a/llvm/include/llvm/Analysis/HashRecognize.h
+++ b/llvm/include/llvm/Analysis/HashRecognize.h
@@ -50,6 +50,9 @@ struct CRCBarrettConstants {
   // CRCBW+1.
   APInt FullGenPoly;
 
+  LLVM_ABI CRCBarrettConstants(const APInt &Mu, const APInt &FullGenPoly)
+      : Mu(Mu), FullGenPoly(FullGenPoly) {}
+
   LLVM_ABI void print(raw_ostream &OS) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index 44ae6eceb3167..dc119e4021f31 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -390,17 +390,12 @@ static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
   // The Poly argument should never be zero, or else this underflows.
   auto Deg = [](const APInt &Poly) { return Poly.getActiveBits() - 1; };
 
-  // Calculate deg(Divisor) once since it never changes.
-  unsigned DivisorDeg = Deg(Divisor);
-  // Only calculate deg(Dividend) after Dividend is known to be nonzero.
-  unsigned DividendDeg;
-
   // Q = 0
   APInt Quotient = APInt::getZero(Dividend.getBitWidth());
   // S != 0 and deg(S) >= deg(P)
-  while (!Dividend.isZero() && (DividendDeg = Deg(Dividend)) >= DivisorDeg) {
+  while (!Dividend.isZero() && Deg(Dividend) >= Deg(Divisor)) {
     // T = S[deg(S)] / P[deg(P)]
-    unsigned Shift = DividendDeg - DivisorDeg;
+    unsigned Shift = Deg(Dividend) - Deg(Divisor);
     // Q = Q + T
     Quotient.setBit(Shift);
     // S = S - T * P
@@ -420,19 +415,19 @@ CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
 
   // Recover the full generating polynomial in normal form by reflecting the LE
   // case and adding the implied x^CRCBW term.
-  APInt FullGenPoly = IsBigEndian ? GenPoly : GenPoly.reverseBits();
   // deg(P(x)) = CRCBW due to the implied term, and thus P(x) must fit in
   // exactly CRCBW+1 bits.
-  FullGenPoly = FullGenPoly.zext(CRCBW + 1);
+  APInt FullGenPoly =
+      (IsBigEndian ? GenPoly : GenPoly.reverseBits()).zext(CRCBW + 1);
   FullGenPoly.setBit(CRCBW);
 
   // Calculate mu = floor(x^(CRCBW+DataBW) / P(x)).
-  unsigned DivBW = CRCBW + DataBW + 1;
-  APInt Mu =
-      floorDivideGF2(APInt::getOneBitSet(DivBW, CRCBW + DataBW), FullGenPoly);
   // deg(mu) <= deg(x^(CRCBW+DataBW)) - deg(P(x)) = CRCBW+DataBW - CRCBW =
   // DataBW, and thus mu must fit in at most DataBW+1 bits.
-  Mu = Mu.trunc(DataBW + 1);
+  unsigned DivBW = CRCBW + DataBW + 1;
+  APInt Mu =
+      floorDivideGF2(APInt::getOneBitSet(DivBW, CRCBW + DataBW), FullGenPoly)
+          .trunc(DataBW + 1);
 
   // In the bit-reflected case, mu and P(x) must be bit-reflected across their
   // respective widths for the corresponding Barrett reduction steps.
@@ -446,10 +441,7 @@ CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
   unsigned ClmulBW = 2 * std::max(CRCBW, DataBW);
 
   // Finally, cast mu/mu' and P(x)/P(x)' to the width used for clmul operations.
-  CRCBarrettConstants Constants;
-  Constants.Mu = Mu.zext(ClmulBW);
-  Constants.FullGenPoly = FullGenPoly.zext(ClmulBW);
-  return Constants;
+  return {Mu.zext(ClmulBW), FullGenPoly.zext(ClmulBW)};
 }
 
 /// Checks that \p P1 and \p P2 are used together in an XOR in the use-def chain
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index b7c8d3be2b4e1..3f3392f1f89c7 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1553,6 +1553,7 @@ bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
 
 bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   Type *CRCTy = Info.LHS->getType();
+  LLVMContext &Ctx = CRCTy->getContext();
   unsigned CRCBW = CRCTy->getIntegerBitWidth();
   // The TripCount determines how many bits of data are processed, regardless of
   // whether the actual data bit width matches (if auxiliary data is even used
@@ -1561,14 +1562,14 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // The width used for clmul operations should be a power of 2, and should be
   // at least CRCBW + DataBW.
   unsigned ClmulBW = 2 * std::max(CRCBW, EffectiveDataBW);
-  Type *ClmulTy = IntegerType::get(CRCTy->getContext(), ClmulBW);
+  Type *ClmulTy = IntegerType::get(Ctx, ClmulBW);
 
   // For big-endian CRC loops where the auxiliary data is XORed with the CRC
   // inside the loop, the bits won't be aligned properly if the bit widths don't
   // match, and thus the CRC computation is incorrect, but HashRecognize will
   // still detect the loop. Since this optimization always produces a correct
   // CRC computation, bail in this edge case.
-  if (Info.ByteOrderSwapped && Info.LHSAux &&
+  if (Info.IsBigEndian && Info.LHSAux &&
       (EffectiveDataBW != CRCBW ||
        Info.LHSAux->getType()->getIntegerBitWidth() != CRCBW))
     return false;
@@ -1583,9 +1584,9 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // First, generate the constants required for GF(2) Barrett reduction.
   CRCBarrettConstants Constants = HashRecognize::genBarrettConstants(
       Info.RHS, EffectiveDataBW, Info.IsBigEndian);
-  Value *Mu = ConstantInt::get(ClmulTy, Constants.Mu.zext(ClmulBW));
+  Value *Mu = ConstantInt::get(Ctx, Constants.Mu.zext(ClmulBW));
   Value *FullGenPoly =
-      ConstantInt::get(ClmulTy, Constants.FullGenPoly.zext(ClmulBW));
+      ConstantInt::get(Ctx, Constants.FullGenPoly.zext(ClmulBW));
 
   IRBuilder<> Builder(CurLoop->getLoopPreheader()->getTerminator());
 
@@ -1608,26 +1609,24 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   Value *ClmulMuInput = CRCAlignData;
   if (Value *Data = Info.LHSAux) {
     unsigned ActualDataBW = Data->getType()->getIntegerBitWidth();
-    if (ActualDataBW > EffectiveDataBW) {
+    if (ActualDataBW > EffectiveDataBW)
       // Extract the useful bits of the data and discard the rest.
-      Data = Info.IsBigEndian
-                 ? Builder.CreateLShr(Data, ActualDataBW - EffectiveDataBW,
-                                      "data.be.lshr")
-                 : Builder.CreateAnd(
-                       Data,
-                       ConstantInt::get(
-                           Data->getType(),
-                           APInt::getLowBitsSet(ActualDataBW, EffectiveDataBW)),
-                       "data.le.mask");
-    }
+      Data =
+          Info.IsBigEndian
+              ? Builder.CreateLShr(Data, ActualDataBW - EffectiveDataBW,
+                                   "data.be.lshr")
+              : Builder.CreateAnd(
+                    Data,
+                    ConstantInt::get(Ctx, APInt::getLowBitsSet(
+                                              ActualDataBW, EffectiveDataBW)),
+                    "data.le.mask");
     // This isn't necessarily a zext-- ActualDataBW could be greater than
     // ClmulBW.
     Value *DataExt = Builder.CreateZExtOrTrunc(Data, ClmulTy, "data.ext");
     // For the big-endian case, ensure the data is aligned properly.
-    if (Info.IsBigEndian && EffectiveDataBW > ActualDataBW) {
+    if (Info.IsBigEndian && EffectiveDataBW > ActualDataBW)
       DataExt = Builder.CreateShl(DataExt, EffectiveDataBW - ActualDataBW,
                                   "data.be.shl");
-    }
 
     ClmulMuInput = Builder.CreateXor(CRCAlignData, DataExt, "xor.crc.data");
   }
@@ -1644,7 +1643,7 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
           : Builder.CreateAnd(
                 ClmulMu,
                 ConstantInt::get(
-                    ClmulTy, APInt::getLowBitsSet(ClmulBW, EffectiveDataBW)),
+                    Ctx, APInt::getLowBitsSet(ClmulBW, EffectiveDataBW)),
                 "quot.le.mask");
 
   // Perform the second clmul operation with the P(x)/P(x)' constant. Input is
@@ -1657,16 +1656,14 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // leftmost bit of the clmul result. For the little-endian case, align the
   // rightmost bits (nothing to do).
   Value *CRCAlignClmul = CRCExt;
-  if (Info.IsBigEndian) {
+  if (Info.IsBigEndian)
     CRCAlignClmul = Builder.CreateShl(CRCExt, EffectiveDataBW, "crc.be.shl");
-  }
   // Get the remainder by subtracting (XORing) the calculated multiple of
   // GenPoly from the CRC.
   Value *CRCNext = Builder.CreateXor(CRCAlignClmul, ClmulGP, "xor.crc.mult");
   // For the little-endian case, the leftmost bits of the XOR are relevant.
-  if (!Info.IsBigEndian) {
+  if (!Info.IsBigEndian)
     CRCNext = Builder.CreateLShr(CRCNext, EffectiveDataBW, "crc.le.lshr");
-  }
   CRCNext = Builder.CreateTrunc(CRCNext, CRCTy, "crc.next");
 
   // Replace the result of the loop with the new computed CRC value.

>From 1d0ae3f2dca011a570e42fd0af6fa5b35361c6f1 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Wed, 24 Jun 2026 18:05:01 -0500
Subject: [PATCH 07/18] Fix misconfigured RISCV regression test

---
 .../RISCV/cyclic-redundancy-check.ll          | 609 ++++++++++++------
 1 file changed, 400 insertions(+), 209 deletions(-)

diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 1744b4d6185ea..8f2185fb0625f 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -1,8 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
-; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,ALL32,NOZBC,NOZBC32 %s
-; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ALL32,ZBC,ZBC32 %s
-; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,ALL64,NOZBC,NOZBC64 %s
-; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ALL64,ZBC,ZBC64 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,NOZBC,NOZBC32 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ZBC,ZBC32 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,NOZBC,NOZBC64 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ZBC,ZBC64 %s
 
 ;.
 ; NOZBC32: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
@@ -93,28 +93,51 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ALL64-LABEL: define i16 @crc16.le.tc8(
-; ALL64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    br label %[[LOOP:.*]]
-; ALL64:       [[LOOP]]:
-; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; ALL64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ALL64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
-; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; NOZBC64-LABEL: define i16 @crc16.le.tc8(
+; NOZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.le.tc8(
+; ZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -195,28 +218,51 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ALL64-LABEL: define i16 @crc16.le.tc8.udiv(
-; ALL64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    br label %[[LOOP:.*]]
-; ALL64:       [[LOOP]]:
-; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; ALL64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ALL64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
-; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; NOZBC64-LABEL: define i16 @crc16.le.tc8.udiv(
+; NOZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; NOZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.le.tc8.udiv(
+; ZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
+; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -297,29 +343,53 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ALL64-LABEL: define i16 @crc16.le.tc16(
-; ALL64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    br label %[[LOOP:.*]]
-; ALL64:       [[LOOP]]:
-; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ALL64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
-; ALL64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ALL64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
-; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; NOZBC64-LABEL: define i16 @crc16.le.tc16(
+; NOZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.le.tc16(
+; ZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; ZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -399,28 +469,51 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
-; ALL64-LABEL: define i8 @crc8.le.tc16(
-; ALL64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    br label %[[LOOP:.*]]
-; ALL64:       [[LOOP]]:
-; ALL64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ALL64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ALL64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; ALL64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
-; ALL64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ALL64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
-; ALL64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+; NOZBC64-LABEL: define i8 @crc8.le.tc16(
+; NOZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i8 @crc8.le.tc16(
+; ZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
+; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -499,29 +592,53 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
-; ALL64-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
-; ALL64-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
-; ALL64-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
-; ALL64-NEXT:    br label %[[LOOP:.*]]
-; ALL64:       [[LOOP]]:
-; ALL64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ALL64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ALL64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; NOZBC64-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; NOZBC64-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; NOZBC64-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; ZBC64-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; ZBC64-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; ZBC64-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   %msg.ext = zext i8 %msg to i16
@@ -592,26 +709,47 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
-; ALL64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    br label %[[LOOP:.*]]
-; ALL64:       [[LOOP]]:
-; ALL64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ALL64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ALL64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; NOZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; ZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -679,26 +817,47 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ALL64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
-; ALL64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    br label %[[LOOP:.*]]
-; ALL64:       [[LOOP]]:
-; ALL64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ALL64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ALL64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ALL64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ALL64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ALL64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ALL64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; NOZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; ZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -783,37 +942,69 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; ZBC32-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
 ;
-; ALL64-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
-; ALL64-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
-; ALL64-NEXT:  [[ENTRY:.*]]:
-; ALL64-NEXT:    br label %[[OUTER_LOOP:.*]]
-; ALL64:       [[OUTER_LOOP]]:
-; ALL64-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
-; ALL64-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
-; ALL64-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
-; ALL64-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
-; ALL64:       [[PH]]:
-; ALL64-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
-; ALL64-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
-; ALL64-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
-; ALL64-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
-; ALL64-NEXT:    br label %[[INNER_LOOP:.*]]
-; ALL64:       [[INNER_LOOP]]:
-; ALL64-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
-; ALL64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
-; ALL64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
-; ALL64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i64 [[INDEXER_EXT]]
-; ALL64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; ALL64-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
-; ALL64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
-; ALL64-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
-; ALL64:       [[INNER_EXIT]]:
-; ALL64-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
-; ALL64-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
-; ALL64-NEXT:    br label %[[OUTER_LOOP]]
-; ALL64:       [[EXIT]]:
-; ALL64-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
-; ALL64-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+; NOZBC64-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; NOZBC64-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[OUTER_LOOP:.*]]
+; NOZBC64:       [[OUTER_LOOP]]:
+; NOZBC64-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; NOZBC64-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; NOZBC64-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; NOZBC64-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; NOZBC64:       [[PH]]:
+; NOZBC64-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; NOZBC64-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; NOZBC64-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; NOZBC64-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; NOZBC64-NEXT:    br label %[[INNER_LOOP:.*]]
+; NOZBC64:       [[INNER_LOOP]]:
+; NOZBC64-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC64-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; NOZBC64:       [[INNER_EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; NOZBC64-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; NOZBC64-NEXT:    br label %[[OUTER_LOOP]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; NOZBC64-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+;
+; ZBC64-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; ZBC64-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[OUTER_LOOP:.*]]
+; ZBC64:       [[OUTER_LOOP]]:
+; ZBC64-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; ZBC64-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; ZBC64-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; ZBC64-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; ZBC64:       [[PH]]:
+; ZBC64-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; ZBC64-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; ZBC64-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; ZBC64-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; ZBC64-NEXT:    br label %[[INNER_LOOP:.*]]
+; ZBC64:       [[INNER_LOOP]]:
+; ZBC64-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ZBC64-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; ZBC64:       [[INNER_EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; ZBC64-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; ZBC64-NEXT:    br label %[[OUTER_LOOP]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; ZBC64-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
 ;
 entry:
   br label %outer.loop
@@ -978,28 +1169,6 @@ exit:                                              ; preds = %loop
 }
 
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
-; ALL32-LABEL: define i32 @crc.disabled.optsize(
-; ALL32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
-; ALL32-NEXT:  [[ENTRY:.*]]:
-; ALL32-NEXT:    br label %[[LOOP:.*]]
-; ALL32:       [[LOOP]]:
-; ALL32-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ALL32-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ALL32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ALL32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; ALL32-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; ALL32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; ALL32-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; ALL32-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; ALL32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; ALL32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ALL32-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; ALL32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ALL32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
-; ALL32:       [[EXIT]]:
-; ALL32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
-; ALL32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC-LABEL: define i32 @crc.disabled.optsize(
 ; NOZBC-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
 ; NOZBC-NEXT:  [[ENTRY:.*]]:
@@ -1022,6 +1191,28 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; NOZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
 ; NOZBC-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
+; ZBC32-LABEL: define i32 @crc.disabled.optsize(
+; ZBC32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ZBC32-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC32-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
 ; ZBC64-LABEL: define i32 @crc.disabled.optsize(
 ; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
 ; ZBC64-NEXT:  [[ENTRY:.*]]:

>From 9342d8e5fe8e556f1b9861077edf968d5c6963c6 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Wed, 24 Jun 2026 18:08:00 -0500
Subject: [PATCH 08/18] Remove unnecessary LLVM_ABI

---
 llvm/include/llvm/Analysis/HashRecognize.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Analysis/HashRecognize.h b/llvm/include/llvm/Analysis/HashRecognize.h
index 0be563b284826..479f69bc94272 100644
--- a/llvm/include/llvm/Analysis/HashRecognize.h
+++ b/llvm/include/llvm/Analysis/HashRecognize.h
@@ -50,7 +50,7 @@ struct CRCBarrettConstants {
   // CRCBW+1.
   APInt FullGenPoly;
 
-  LLVM_ABI CRCBarrettConstants(const APInt &Mu, const APInt &FullGenPoly)
+  CRCBarrettConstants(const APInt &Mu, const APInt &FullGenPoly)
       : Mu(Mu), FullGenPoly(FullGenPoly) {}
 
   LLVM_ABI void print(raw_ostream &OS) const;

>From 2b4274459317504206888e998cc63a7f6bcdfa67 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Thu, 25 Jun 2026 14:05:57 -0500
Subject: [PATCH 09/18] Apply some suggested changes

---
 llvm/include/llvm/Analysis/HashRecognize.h    |   2 +-
 llvm/include/llvm/CodeGen/BasicTTIImpl.h      |   9 +-
 llvm/lib/Analysis/HashRecognize.cpp           |  44 +--
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 123 ++++----
 .../HashRecognize/cyclic-redundancy-check.ll  |  20 +-
 .../AArch64/cyclic-redundancy-check.ll        | 295 +++++------------
 .../RISCV/cyclic-redundancy-check.ll          | 298 ++++++------------
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  | 287 +++++------------
 8 files changed, 361 insertions(+), 717 deletions(-)

diff --git a/llvm/include/llvm/Analysis/HashRecognize.h b/llvm/include/llvm/Analysis/HashRecognize.h
index 479f69bc94272..1ab3fe6b31c9b 100644
--- a/llvm/include/llvm/Analysis/HashRecognize.h
+++ b/llvm/include/llvm/Analysis/HashRecognize.h
@@ -116,7 +116,7 @@ class HashRecognize {
   // Auxilary entry point after analysis to generate constants for a GF(2)
   // Barrett Reduction.
   LLVM_ABI static CRCBarrettConstants
-  genBarrettConstants(const APInt &GenPoly, unsigned DataBW,
+  genBarrettConstants(const APInt &GenPoly, unsigned TripCount,
                       bool ByteOrderSwapped);
 
   LLVM_ABI void print(raw_ostream &OS) const;
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index c369c928b9eb4..8841faa7b3fbb 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -677,10 +677,15 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
   }
 
   bool haveFastClmul(Type *Ty) const override {
+    // FIXME: clmul should really be Promote for any bitwidth under the largest
+    // legal bitwidth for clmul. This is a hack to get around that shortcoming.
+    if (auto *IntTy = dyn_cast<IntegerType>(Ty))
+      if (Type *PromoteTy = DL.getSmallestLegalIntType(Ty->getContext(),
+                                                       IntTy->getBitWidth()))
+        Ty = PromoteTy;
     const TargetLoweringBase *TLI = getTLI();
     EVT VT = TLI->getValueType(DL, Ty);
-    return TLI->isTypeLegal(VT) &&
-           TLI->isOperationLegalOrCustomOrPromote(ISD::CLMUL, VT);
+    return TLI->isOperationLegalOrCustomOrPromote(ISD::CLMUL, VT);
   }
 
   bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override { return true; }
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index dc119e4021f31..fd520f89cfb06 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -407,27 +407,28 @@ static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
 // Generate the constants for performing a Polynomial (GF(2)) Barrett Reduction
 // according to Intel's Fast CRC Computation white paper
 // (https://www.researchgate.net/publication/263424619_Fast_CRC_computation),
-// with some adjustments to account for the fact that CRCBW and DataBW can vary.
+// with some adjustments to account for the fact that bit width and trip count
+// can vary.
 CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
-                                                       unsigned DataBW,
+                                                       unsigned TripCount,
                                                        bool IsBigEndian) {
-  unsigned CRCBW = GenPoly.getBitWidth();
+  unsigned BW = GenPoly.getBitWidth();
 
   // Recover the full generating polynomial in normal form by reflecting the LE
-  // case and adding the implied x^CRCBW term.
-  // deg(P(x)) = CRCBW due to the implied term, and thus P(x) must fit in
-  // exactly CRCBW+1 bits.
+  // case and adding the implied x^BW term.
+  // deg(P(x)) = BW due to the implied term, and thus P(x) must fit in exactly
+  // BW+1 bits.
   APInt FullGenPoly =
-      (IsBigEndian ? GenPoly : GenPoly.reverseBits()).zext(CRCBW + 1);
-  FullGenPoly.setBit(CRCBW);
+      (IsBigEndian ? GenPoly : GenPoly.reverseBits()).zext(BW + 1);
+  FullGenPoly.setBit(BW);
 
-  // Calculate mu = floor(x^(CRCBW+DataBW) / P(x)).
-  // deg(mu) <= deg(x^(CRCBW+DataBW)) - deg(P(x)) = CRCBW+DataBW - CRCBW =
-  // DataBW, and thus mu must fit in at most DataBW+1 bits.
-  unsigned DivBW = CRCBW + DataBW + 1;
+  // Calculate mu = floor(x^(BW+TC) / P(x)).
+  // deg(mu) <= deg(x^(BW+TC)) - deg(P(x)) = BW+TC - BW = TC, and thus mu must
+  // fit in at most TC+1 bits.
+  unsigned DivBW = BW + TripCount + 1;
   APInt Mu =
-      floorDivideGF2(APInt::getOneBitSet(DivBW, CRCBW + DataBW), FullGenPoly)
-          .trunc(DataBW + 1);
+      floorDivideGF2(APInt::getOneBitSet(DivBW, BW + TripCount), FullGenPoly)
+          .trunc(TripCount + 1);
 
   // In the bit-reflected case, mu and P(x) must be bit-reflected across their
   // respective widths for the corresponding Barrett reduction steps.
@@ -436,12 +437,9 @@ CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
     FullGenPoly = FullGenPoly.reverseBits();
   }
 
-  // The width used for clmul operations should be a power of 2, and should be
-  // at least CRCBW + DataBW.
-  unsigned ClmulBW = 2 * std::max(CRCBW, DataBW);
-
-  // Finally, cast mu/mu' and P(x)/P(x)' to the width used for clmul operations.
-  return {Mu.zext(ClmulBW), FullGenPoly.zext(ClmulBW)};
+  // The final constants are mu/mu' and P(x)/P(x)', depending on
+  // IsBigEndian.
+  return {Mu, FullGenPoly};
 }
 
 /// Checks that \p P1 and \p P2 are used together in an XOR in the use-def chain
@@ -600,7 +598,11 @@ void CRCTable::dump() const { print(dbgs()); }
 #endif
 
 void CRCBarrettConstants::print(raw_ostream &OS) const {
-  OS << "Reciprocal = " << Mu << ", Generator = " << FullGenPoly << '\n';
+  OS << "Mu = ";
+  Mu.print(OS, false);
+  OS << ", FullGenPoly = ";
+  FullGenPoly.print(OS, false);
+  OS << '\n';
 }
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 3f3392f1f89c7..13f1a0040306a 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1558,10 +1558,10 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // The TripCount determines how many bits of data are processed, regardless of
   // whether the actual data bit width matches (if auxiliary data is even used
   // at all).
-  unsigned EffectiveDataBW = Info.TripCount;
-  // The width used for clmul operations should be a power of 2, and should be
-  // at least CRCBW + DataBW.
-  unsigned ClmulBW = 2 * std::max(CRCBW, EffectiveDataBW);
+  unsigned TC = Info.TripCount;
+  // The first clmul uses 2*TC bits, and the second clmul uses CRCBW+TC bits.
+  // For simplicity, have both operate on the same bit width.
+  unsigned ClmulBW = std::max(2 * TC, CRCBW + TC);
   Type *ClmulTy = IntegerType::get(Ctx, ClmulBW);
 
   // For big-endian CRC loops where the auxiliary data is XORed with the CRC
@@ -1570,85 +1570,82 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // still detect the loop. Since this optimization always produces a correct
   // CRC computation, bail in this edge case.
   if (Info.IsBigEndian && Info.LHSAux &&
-      (EffectiveDataBW != CRCBW ||
-       Info.LHSAux->getType()->getIntegerBitWidth() != CRCBW))
+      (TC != CRCBW || Info.LHSAux->getType()->getIntegerBitWidth() != CRCBW))
     return false;
 
-  // This optimization should not be applied if there is no fast clmul operation
-  // for the required width on the target.
-  // TODO: If EffectiveDataBW > CRCBW, then the data could probably be split
-  // into multiple chunks and processed in a loop.
+  // This optimization should only be applied if clmul for the required width is
+  // a fast operation on the target.
+  // TODO: If TC > CRCBW, then the data could probably be split into multiple
+  // chunks and processed in a loop.
   if (!TTI->haveFastClmul(ClmulTy))
     return false;
 
   // First, generate the constants required for GF(2) Barrett reduction.
-  CRCBarrettConstants Constants = HashRecognize::genBarrettConstants(
-      Info.RHS, EffectiveDataBW, Info.IsBigEndian);
+  CRCBarrettConstants Constants =
+      HashRecognize::genBarrettConstants(Info.RHS, TC, Info.IsBigEndian);
   Value *Mu = ConstantInt::get(Ctx, Constants.Mu.zext(ClmulBW));
   Value *FullGenPoly =
       ConstantInt::get(Ctx, Constants.FullGenPoly.zext(ClmulBW));
 
+  // Mark all PHIs for removal since we're getting rid of the loop.
+  SmallVector<PHINode *, 2> Cleanup;
+  for (PHINode &PN : CurLoop->getHeader()->phis()) {
+    PN.replaceAllUsesWith(PoisonValue::get(PN.getType()));
+    Cleanup.push_back(&PN);
+  }
+
   IRBuilder<> Builder(CurLoop->getLoopPreheader()->getTerminator());
 
   Value *CRCExt = Builder.CreateZExt(Info.LHS, ClmulTy, "crc.ext");
 
   // For the big-endian case, align the leftmost bit of the CRC with the
-  // leftmost bit of the data. For the little-endian case, align the rightmost
-  // bits (nothing to do).
-  Value *CRCAlignData = CRCExt;
+  // leftmost bit of the data which is used. For the little-endian case, align
+  // the rightmost bits (nothing to do).
+  Value *CRCAlignTC = CRCExt;
   if (Info.IsBigEndian) {
-    if (CRCBW > EffectiveDataBW)
-      CRCAlignData = Builder.CreateLShr(CRCAlignData, CRCBW - EffectiveDataBW,
-                                        "crc.be.lshr");
-    else if (EffectiveDataBW > CRCBW)
-      CRCAlignData = Builder.CreateShl(CRCAlignData, EffectiveDataBW - CRCBW,
-                                       "crc.be.shl");
+    if (CRCBW > TC)
+      CRCAlignTC = Builder.CreateLShr(CRCAlignTC, CRCBW - TC, "crc.be.lshr");
+    else if (TC > CRCBW)
+      CRCAlignTC = Builder.CreateShl(CRCAlignTC, TC - CRCBW, "crc.be.shl");
   }
 
   // If auxiliary data is present, XOR it in with the CRC.
-  Value *ClmulMuInput = CRCAlignData;
+  Value *ClmulMuInput = CRCAlignTC;
   if (Value *Data = Info.LHSAux) {
-    unsigned ActualDataBW = Data->getType()->getIntegerBitWidth();
-    if (ActualDataBW > EffectiveDataBW)
+    unsigned DataBW = Data->getType()->getIntegerBitWidth();
+    if (DataBW > TC) {
       // Extract the useful bits of the data and discard the rest.
-      Data =
-          Info.IsBigEndian
-              ? Builder.CreateLShr(Data, ActualDataBW - EffectiveDataBW,
-                                   "data.be.lshr")
-              : Builder.CreateAnd(
-                    Data,
-                    ConstantInt::get(Ctx, APInt::getLowBitsSet(
-                                              ActualDataBW, EffectiveDataBW)),
-                    "data.le.mask");
-    // This isn't necessarily a zext-- ActualDataBW could be greater than
-    // ClmulBW.
-    Value *DataExt = Builder.CreateZExtOrTrunc(Data, ClmulTy, "data.ext");
-    // For the big-endian case, ensure the data is aligned properly.
-    if (Info.IsBigEndian && EffectiveDataBW > ActualDataBW)
-      DataExt = Builder.CreateShl(DataExt, EffectiveDataBW - ActualDataBW,
-                                  "data.be.shl");
-
-    ClmulMuInput = Builder.CreateXor(CRCAlignData, DataExt, "xor.crc.data");
-  }
-
-  // Perform the first clmul operation with the mu/mu' constant. Input is DataBW
-  // bits and Mu is DataBW+1 bits, so the result will be 2*DataBW bits.
+      if (Info.IsBigEndian) {
+        Data = Builder.CreateLShr(Data, DataBW - TC, "data.be.lshr");
+      } else {
+        ConstantInt *Mask =
+            ConstantInt::get(Ctx, APInt::getLowBitsSet(DataBW, TC));
+        Data = Builder.CreateAnd(Data, Mask, "data.le.mask");
+      }
+    }
+    // This is always a zext since TripCount <= DataBW < ClmulBW.
+    Value *DataExt = Builder.CreateZExt(Data, ClmulTy, "data.ext");
+
+    ClmulMuInput = Builder.CreateXor(CRCAlignTC, DataExt, "xor.crc.data");
+  }
+
+  // Perform the first clmul operation with the mu/mu' constant. Input is TC
+  // bits and Mu is TC+1 bits, so the result will be 2*TC bits.
   Value *ClmulMu = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulMuInput,
                                                  Mu, {}, "clmul.mu");
 
-  // Extract the relevant DataBW bits from the result.
-  Value *ClmulGPInput =
-      Info.IsBigEndian
-          ? Builder.CreateLShr(ClmulMu, EffectiveDataBW, "quot.be.lshr")
-          : Builder.CreateAnd(
-                ClmulMu,
-                ConstantInt::get(
-                    Ctx, APInt::getLowBitsSet(ClmulBW, EffectiveDataBW)),
-                "quot.le.mask");
+  // Extract the relevant bits from the result.
+  Value *ClmulGPInput;
+  if (Info.IsBigEndian) {
+    ClmulGPInput = Builder.CreateLShr(ClmulMu, TC, "quot.be.lshr");
+  } else {
+    ConstantInt *Mask =
+        ConstantInt::get(Ctx, APInt::getLowBitsSet(ClmulBW, TC));
+    ClmulGPInput = Builder.CreateAnd(ClmulMu, Mask, "quot.le.mask");
+  }
 
   // Perform the second clmul operation with the P(x)/P(x)' constant. Input is
-  // DataBW bits and GP is CRCBW+1 bits, so the result will be CRCBW+DataBW
-  // bits.
+  // TC bits and GP is CRCBW+1 bits, so the result will be CRCBW+TC bits.
   Value *ClmulGP = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulGPInput,
                                                  FullGenPoly, {}, "clmul.gp");
 
@@ -1657,18 +1654,26 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // rightmost bits (nothing to do).
   Value *CRCAlignClmul = CRCExt;
   if (Info.IsBigEndian)
-    CRCAlignClmul = Builder.CreateShl(CRCExt, EffectiveDataBW, "crc.be.shl");
+    CRCAlignClmul = Builder.CreateShl(CRCExt, TC, "crc.be.shl");
+
   // Get the remainder by subtracting (XORing) the calculated multiple of
   // GenPoly from the CRC.
   Value *CRCNext = Builder.CreateXor(CRCAlignClmul, ClmulGP, "xor.crc.mult");
+
   // For the little-endian case, the leftmost bits of the XOR are relevant.
   if (!Info.IsBigEndian)
-    CRCNext = Builder.CreateLShr(CRCNext, EffectiveDataBW, "crc.le.lshr");
+    CRCNext = Builder.CreateLShr(CRCNext, TC, "crc.le.lshr");
   CRCNext = Builder.CreateTrunc(CRCNext, CRCTy, "crc.next");
 
   // Replace the result of the loop with the new computed CRC value.
   Info.ComputedValue->replaceUsesOutsideBlock(CRCNext, CurLoop->getLoopLatch());
 
+  // Get rid of the loop completely.
+  for (PHINode *PN : Cleanup)
+    RecursivelyDeleteDeadPHINode(PN);
+  MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr;
+  deleteDeadLoop(CurLoop, DT, SE, LI, MSSA);
+
   return true;
 }
 
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index 43b643f0ea8ba..fe404e76812e1 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -26,7 +26,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 511, Generator = 81923
+; CHECK-NEXT:  Mu = 511, FullGenPoly = 81923
 ;
 entry:
   br label %loop
@@ -76,7 +76,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 511, Generator = 81923
+; CHECK-NEXT:  Mu = 511, FullGenPoly = 81923
 ;
 entry:
   br label %loop
@@ -126,7 +126,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; CHECK-NEXT:  34817 18624 18816 35137 19200 35777 35457 19008 19968 36545 36737 20288 36097 19904 19584 35905
 ; CHECK-NEXT:  17408 33985 34177 17728 34561 18368 18048 34369 33281 17088 17280 33601 16640 33217 32897 16448
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 114687, Generator = 81923
+; CHECK-NEXT:  Mu = 114687, FullGenPoly = 81923
 ;
 entry:
   br label %loop
@@ -175,7 +175,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; CHECK-NEXT:  26 19 8 1 5 12 23 30 31 22 13 4 0 9 18 27
 ; CHECK-NEXT:  16 25 2 11 15 6 29 20 21 28 7 14 10 3 24 17
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 24423, Generator = 59
+; CHECK-NEXT:  Mu = 24423, FullGenPoly = 59
 ;
 entry:
   br label %loop
@@ -224,7 +224,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 273, Generator = 69665
+; CHECK-NEXT:  Mu = 273, FullGenPoly = 69665
 ;
 entry:
   %msg.ext = zext i8 %msg to i16
@@ -271,7 +271,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 273, Generator = 69665
+; CHECK-NEXT:  Mu = 273, FullGenPoly = 69665
 ;
 entry:
   br label %loop
@@ -315,7 +315,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
 ; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 273, Generator = 69665
+; CHECK-NEXT:  Mu = 273, FullGenPoly = 69665
 ;
 entry:
   br label %loop
@@ -359,7 +359,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; CHECK-NEXT:  178 175 136 149 198 219 252 225 90 71 96 125 46 51 20 9
 ; CHECK-NEXT:  127 98 69 88 11 22 49 44 151 138 173 176 227 254 217 196
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 284, Generator = 285
+; CHECK-NEXT:  Mu = 284, FullGenPoly = 285
 ;
 entry:
   br label %outer.loop
@@ -421,7 +421,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; CHECK-NEXT:  59150 63111 50204 54677 41258 45219 33336 37809 27462 31439 18516 23005 11618 15595 3696 8185
 ; CHECK-NEXT:  63375 58886 54429 50452 45483 40994 37561 33584 31687 27214 22741 18780 15843 11370 7921 3960
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 273, Generator = 67601
+; CHECK-NEXT:  Mu = 273, FullGenPoly = 67601
 ;
 entry:
   br label %loop
@@ -470,7 +470,7 @@ define i16 @crc16.be.tc8.zext.data(i8 %msg, i16 %checksum) {
 ; CHECK-NEXT:  57792 57538 58308 58054 58824 58570 59340 59086 59856 59602 60372 60118 60888 60634 61404 61150
 ; CHECK-NEXT:  61920 61666 62436 62182 62952 62698 63468 63214 63984 63730 64500 64246 65016 64762 65532 65278
 ; CHECK-NEXT:    Computed CRC Barrett constants:
-; CHECK-NEXT:  Reciprocal = 257, Generator = 65794
+; CHECK-NEXT:  Mu = 257, FullGenPoly = 65794
 ;
 entry:
   br label %loop
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index e9513386d4b42..e83ee1676836e 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -13,8 +13,6 @@
 ; NOAES: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOAES: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
-; AES: @.crctable = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOAES-LABEL: define i16 @crc16.le.tc8(
 ; NOAES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -42,33 +40,18 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; AES-LABEL: define i16 @crc16.le.tc8(
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
-; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
-; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
-; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
-; AES-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
-; AES-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
-; AES-NEXT:    [[DATA_NEXT]] = lshr i8 [[DATA]], 1
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
-; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
-; AES-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -121,33 +104,18 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; AES-LABEL: define i16 @crc16.le.tc8.udiv(
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
-; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
-; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
-; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
-; AES-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
-; AES-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
-; AES-NEXT:    [[DATA_NEXT]] = udiv i8 [[DATA]], 2
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
-; AES-NEXT:    [[CRC_LSHR:%.*]] = udiv i16 [[CRC]], 2
-; AES-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -210,23 +178,9 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
-; AES-NEXT:    [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
-; AES-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
-; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
-; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -287,24 +241,9 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
-; AES-NEXT:    [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
-; AES-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
-; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
-; AES-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -361,27 +300,17 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; AES-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; AES-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; AES-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
-; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -430,27 +359,17 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
-; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -496,27 +415,17 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
-; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; AES-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp sge i16 [[CRC]], 0
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -584,18 +493,16 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; AES-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
 ; AES-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
 ; AES-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
-; AES-NEXT:    br label %[[INNER_LOOP:.*]]
-; AES:       [[INNER_LOOP]]:
-; AES-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
-; AES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
-; AES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
-; AES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i64 [[INDEXER_EXT]]
-; AES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; AES-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
-; AES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
-; AES-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CRC_INIT]] to i16
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_EXT]], i16 284)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
+; AES-NEXT:    br label %[[INNER_EXIT]]
 ; AES:       [[INNER_EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[PH]] ]
 ; AES-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; AES-NEXT:    br label %[[OUTER_LOOP]]
 ; AES:       [[EXIT]]:
@@ -665,33 +572,19 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; AES-LABEL: define i32 @crc32.le.tc8.data32(
 ; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
-; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
-; AES-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
-; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; AES-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; AES-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -742,33 +635,19 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; AES-LABEL: define i32 @crc.disabled.optsize(
 ; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
 ; AES-NEXT:  [[ENTRY:.*]]:
-; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
-; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
-; AES-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
-; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
-; AES-NEXT:    br label %[[LOOP:.*]]
-; AES:       [[LOOP]]:
-; AES-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; AES-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; AES-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; AES-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; AES-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; AES-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; AES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; AES-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
+; AES-NEXT:    br label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 8f2185fb0625f..5c67073c37dfc 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -15,8 +15,7 @@
 ; NOZBC32: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOZBC32: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
-; ZBC32: @.crctable = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; ZBC32: @.crctable.1 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; ZBC32: @.crctable = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 ; NOZBC64: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
 ; NOZBC64: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
@@ -64,33 +63,18 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; ZBC32-LABEL: define i16 @crc16.le.tc8(
 ; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
-; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
-; ZBC32-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
-; ZBC32-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
-; ZBC32-NEXT:    [[DATA_NEXT]] = lshr i8 [[DATA]], 1
-; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
-; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
-; ZBC32-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
+; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; ZBC32-NEXT:    br label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc8(
@@ -189,33 +173,18 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; ZBC32-LABEL: define i16 @crc16.le.tc8.udiv(
 ; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
-; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
-; ZBC32-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
-; ZBC32-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
-; ZBC32-NEXT:    [[DATA_NEXT]] = udiv i8 [[DATA]], 2
-; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
-; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = udiv i16 [[CRC]], 2
-; ZBC32-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
+; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; ZBC32-NEXT:    br label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc8.udiv(
@@ -324,23 +293,9 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
-; ZBC32-NEXT:    [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
-; ZBC32-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
-; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
-; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
-; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc16(
@@ -449,24 +404,9 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
-; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
-; ZBC32-NEXT:    [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
-; ZBC32-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
-; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
-; ZBC32-NEXT:    [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
-; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
-; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i8 @crc8.le.tc16(
@@ -569,27 +509,17 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; ZBC32-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; ZBC32-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
-; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC32-NEXT:    br label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
@@ -686,27 +616,17 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
-; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC32-NEXT:    br label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
@@ -794,27 +714,17 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; ZBC32-NEXT:  [[ENTRY:.*]]:
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; ZBC32-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; ZBC32-NEXT:    [[CHECK_SB:%.*]] = icmp sge i16 [[CRC]], 0
-; ZBC32-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC32-NEXT:    br label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
@@ -924,18 +834,16 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; ZBC32-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
 ; ZBC32-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
 ; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
-; ZBC32-NEXT:    br label %[[INNER_LOOP:.*]]
-; ZBC32:       [[INNER_LOOP]]:
-; ZBC32-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i32
-; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable, i32 [[INDEXER_EXT]]
-; ZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; ZBC32-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CRC_INIT]] to i16
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_EXT]], i16 284)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
+; ZBC32-NEXT:    br label %[[INNER_EXIT]]
 ; ZBC32:       [[INNER_EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[PH]] ]
 ; ZBC32-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; ZBC32-NEXT:    br label %[[OUTER_LOOP]]
 ; ZBC32:       [[EXIT]]:
@@ -1079,7 +987,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
 ; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
 ; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.1, i32 [[INDEXER_EXT]]
+; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable, i32 [[INDEXER_EXT]]
 ; ZBC32-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
 ; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
 ; ZBC32-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
@@ -1117,33 +1025,19 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC64-LABEL: define i32 @crc32.le.tc8.data32(
 ; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
-; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
-; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
-; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
-; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
-; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; ZBC64-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; ZBC64-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; ZBC64-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; ZBC64-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; ZBC64-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
+; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
+; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
+; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
+; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
+; ZBC64-NEXT:    br label %[[EXIT:.*]]
 ; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -1216,33 +1110,19 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; ZBC64-LABEL: define i32 @crc.disabled.optsize(
 ; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
 ; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
-; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
-; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
-; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
-; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
-; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; ZBC64-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; ZBC64-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; ZBC64-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; ZBC64-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; ZBC64-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
+; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
+; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
+; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
+; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
+; ZBC64-NEXT:    br label %[[EXIT:.*]]
 ; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index 4265e9573a0f8..a747fc74395a4 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -40,33 +40,18 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; PCLMUL-LABEL: define i16 @crc16.le.tc8(
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
-; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
-; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
-; PCLMUL-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
-; PCLMUL-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
-; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i8 [[DATA]], 1
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
-; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
-; PCLMUL-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -119,33 +104,18 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; PCLMUL-LABEL: define i16 @crc16.le.tc8.udiv(
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
-; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i32
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA]], i32 511)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 255
-; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
-; PCLMUL-NEXT:    [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
-; PCLMUL-NEXT:    [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
-; PCLMUL-NEXT:    [[DATA_NEXT]] = udiv i8 [[DATA]], 2
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
-; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = udiv i16 [[CRC]], 2
-; PCLMUL-NEXT:    [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -208,23 +178,9 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
-; PCLMUL-NEXT:    [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
-; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
-; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -285,24 +241,9 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
-; PCLMUL-NEXT:    [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
-; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i16 [[DATA]], 1
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
-; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -359,27 +300,17 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; PCLMUL-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; PCLMUL-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; PCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
-; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -428,27 +359,17 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
-; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i16 [[CRC]], 0
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_XOR]], i16 [[CRC_SHL]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -494,27 +415,17 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
-; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i32
-; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i32 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_BE_LSHR]], i32 273)
-; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 8
-; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp sge i16 [[CRC]], 0
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -589,19 +500,9 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
-; PCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
-; PCLMUL:       [[INNER_LOOP]]:
-; PCLMUL-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[CRC_NEXT:%.*]], %[[INNER_LOOP]] ]
-; PCLMUL-NEXT:    [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp slt i8 [[CRC]], 0
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_XOR]], i8 [[CRC_SHL]]
-; PCLMUL-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 [[INNER_IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; PCLMUL-NEXT:    br label %[[INNER_EXIT]]
 ; PCLMUL:       [[INNER_EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[PH]] ]
 ; PCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; PCLMUL-NEXT:    br label %[[OUTER_LOOP]]
 ; PCLMUL:       [[EXIT]]:
@@ -671,33 +572,19 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; PCLMUL-LABEL: define i32 @crc32.le.tc8.data32(
 ; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
-; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
-; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; PCLMUL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -748,33 +635,19 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; PCLMUL-LABEL: define i32 @crc.disabled.optsize(
 ; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*]]:
-; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i64
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i64
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_EXT]], [[DATA_EXT]]
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[XOR_CRC_DATA1]], i64 273)
-; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i64 [[CLMUL_MU]], 255
-; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_LE_MASK]], i64 67601)
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_EXT]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i64 [[XOR_CRC_MULT]], 8
-; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i64 [[CRC_LE_LSHR]] to i32
-; PCLMUL-NEXT:    br label %[[LOOP:.*]]
-; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
-; PCLMUL-NEXT:    [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
-; PCLMUL-NEXT:    [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
-; PCLMUL-NEXT:    [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
-; PCLMUL-NEXT:    [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
-; PCLMUL-NEXT:    [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
-; PCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; PCLMUL-NEXT:    [[DATA_NEXT]] = lshr i32 [[DATA]], 1
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
+; PCLMUL-NEXT:    br label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:

>From e36882ae75f1a9574cf7ef93dbe5d303495e1963 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Thu, 25 Jun 2026 14:34:55 -0500
Subject: [PATCH 10/18] Undo broken change to loop cleanup

---
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  |  3 +-
 .../AArch64/cyclic-redundancy-check.ll        | 88 +++++++++++++------
 .../RISCV/cyclic-redundancy-check.ll          | 88 +++++++++++++------
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  | 88 +++++++++++++------
 4 files changed, 178 insertions(+), 89 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 13f1a0040306a..fa1b3b4e61874 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1671,8 +1671,7 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // Get rid of the loop completely.
   for (PHINode *PN : Cleanup)
     RecursivelyDeleteDeadPHINode(PN);
-  MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr;
-  deleteDeadLoop(CurLoop, DT, SE, LI, MSSA);
+  SE->forgetLoop(CurLoop);
 
   return true;
 }
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index e83ee1676836e..c7f68e9cbc5ff 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -39,7 +39,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ;
 ; AES-LABEL: define i16 @crc16.le.tc8(
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
 ; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
 ; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
@@ -49,9 +49,12 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -103,7 +106,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ;
 ; AES-LABEL: define i16 @crc16.le.tc8.udiv(
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
 ; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
 ; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
@@ -113,9 +116,12 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -168,7 +174,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ;
 ; AES-LABEL: define i16 @crc16.le.tc16(
 ; AES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
 ; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
 ; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
@@ -178,9 +184,12 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -231,7 +240,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ;
 ; AES-LABEL: define i8 @crc8.le.tc16(
 ; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
 ; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
 ; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
@@ -241,9 +250,12 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -296,7 +308,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ;
 ; AES-LABEL: define i16 @crc16.be.tc8.crc.init.li(
 ; AES-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; AES-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; AES-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
@@ -308,9 +320,12 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -358,7 +373,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ;
 ; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
 ; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
@@ -367,9 +382,12 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -414,7 +432,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ;
 ; AES-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
 ; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
@@ -423,9 +441,12 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -500,9 +521,12 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
-; AES-NEXT:    br label %[[INNER_EXIT]]
+; AES-NEXT:    br label %[[INNER_LOOP:.*]]
+; AES:       [[INNER_LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; AES:       [[INNER_EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[PH]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; AES-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; AES-NEXT:    br label %[[OUTER_LOOP]]
 ; AES:       [[EXIT]]:
@@ -571,7 +595,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ;
 ; AES-LABEL: define i32 @crc32.le.tc8.data32(
 ; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
 ; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
@@ -582,9 +606,12 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -634,7 +661,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ;
 ; AES-LABEL: define i32 @crc.disabled.optsize(
 ; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
-; AES-NEXT:  [[ENTRY:.*]]:
+; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
 ; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
@@ -645,9 +672,12 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
 ; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
-; AES-NEXT:    br label %[[EXIT:.*]]
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 5c67073c37dfc..21bc6b3bf8c51 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -62,7 +62,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ;
 ; ZBC32-LABEL: define i16 @crc16.le.tc8(
 ; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:  [[ENTRY:.*:]]
 ; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
 ; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
 ; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
@@ -72,9 +72,12 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc8(
@@ -172,7 +175,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ;
 ; ZBC32-LABEL: define i16 @crc16.le.tc8.udiv(
 ; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:  [[ENTRY:.*:]]
 ; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
 ; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
 ; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
@@ -182,9 +185,12 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc8.udiv(
@@ -283,7 +289,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ;
 ; ZBC32-LABEL: define i16 @crc16.le.tc16(
 ; ZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:  [[ENTRY:.*:]]
 ; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
 ; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
 ; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
@@ -293,9 +299,12 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc16(
@@ -394,7 +403,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ;
 ; ZBC32-LABEL: define i8 @crc8.le.tc16(
 ; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:  [[ENTRY:.*:]]
 ; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
 ; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
 ; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
@@ -404,9 +413,12 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
-; ZBC32-NEXT:    br label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i8 @crc8.le.tc16(
@@ -505,7 +517,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ;
 ; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.li(
 ; ZBC32-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:  [[ENTRY:.*:]]
 ; ZBC32-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; ZBC32-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
@@ -517,9 +529,12 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
@@ -615,7 +630,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ;
 ; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:  [[ENTRY:.*:]]
 ; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
 ; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
 ; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
@@ -624,9 +639,12 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
@@ -713,7 +731,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ;
 ; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:  [[ENTRY:.*:]]
 ; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
 ; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
 ; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
@@ -722,9 +740,12 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[EXIT:.*]]
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
@@ -841,9 +862,12 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
 ; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
-; ZBC32-NEXT:    br label %[[INNER_EXIT]]
+; ZBC32-NEXT:    br label %[[INNER_LOOP:.*]]
+; ZBC32:       [[INNER_LOOP]]:
+; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; ZBC32:       [[INNER_EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[PH]] ]
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; ZBC32-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; ZBC32-NEXT:    br label %[[OUTER_LOOP]]
 ; ZBC32:       [[EXIT]]:
@@ -1024,7 +1048,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ;
 ; ZBC64-LABEL: define i32 @crc32.le.tc8.data32(
 ; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:  [[ENTRY:.*:]]
 ; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
 ; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
@@ -1035,9 +1059,12 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
 ; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
-; ZBC64-NEXT:    br label %[[EXIT:.*]]
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -1109,7 +1136,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ;
 ; ZBC64-LABEL: define i32 @crc.disabled.optsize(
 ; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:  [[ENTRY:.*:]]
 ; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
 ; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
@@ -1120,9 +1147,12 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; ZBC64-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
 ; ZBC64-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
 ; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
-; ZBC64-NEXT:    br label %[[EXIT:.*]]
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index a747fc74395a4..350cddd09cad4 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -39,7 +39,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ;
 ; PCLMUL-LABEL: define i16 @crc16.le.tc8(
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
 ; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
 ; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
@@ -49,9 +49,12 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -103,7 +106,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ;
 ; PCLMUL-LABEL: define i16 @crc16.le.tc8.udiv(
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
 ; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
 ; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
@@ -113,9 +116,12 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -168,7 +174,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ;
 ; PCLMUL-LABEL: define i16 @crc16.le.tc16(
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
 ; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
 ; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
@@ -178,9 +184,12 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -231,7 +240,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ;
 ; PCLMUL-LABEL: define i8 @crc8.le.tc16(
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
 ; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
 ; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
@@ -241,9 +250,12 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -296,7 +308,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ;
 ; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.li(
 ; PCLMUL-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
 ; PCLMUL-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; PCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
@@ -308,9 +320,12 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -358,7 +373,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ;
 ; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
 ; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
@@ -367,9 +382,12 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -414,7 +432,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ;
 ; PCLMUL-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
 ; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
@@ -423,9 +441,12 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -500,9 +521,12 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
-; PCLMUL-NEXT:    br label %[[INNER_EXIT]]
+; PCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
+; PCLMUL:       [[INNER_LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; PCLMUL:       [[INNER_EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[PH]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; PCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
 ; PCLMUL-NEXT:    br label %[[OUTER_LOOP]]
 ; PCLMUL:       [[EXIT]]:
@@ -571,7 +595,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ;
 ; PCLMUL-LABEL: define i32 @crc32.le.tc8.data32(
 ; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
 ; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
@@ -582,9 +606,12 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -634,7 +661,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ;
 ; PCLMUL-LABEL: define i32 @crc.disabled.optsize(
 ; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
-; PCLMUL-NEXT:  [[ENTRY:.*]]:
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
 ; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
@@ -645,9 +672,12 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_EXT]], [[CLMUL_GP]]
 ; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
-; PCLMUL-NEXT:    br label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
+; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[ENTRY]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
 entry:

>From ce866e7215f74bc853bcbca35874cc36ce53cc38 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Fri, 26 Jun 2026 10:52:53 -0500
Subject: [PATCH 11/18] Apply requested changes, improve loop cleanup

---
 llvm/include/llvm/CodeGen/BasicTTIImpl.h      | 10 +++---
 llvm/lib/Analysis/HashRecognize.cpp           |  9 +++---
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 31 ++++++++++++++-----
 .../AArch64/cyclic-redundancy-check.ll        | 30 ++++++------------
 .../RISCV/cyclic-redundancy-check.ll          | 30 ++++++------------
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  | 30 ++++++------------
 6 files changed, 64 insertions(+), 76 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 8841faa7b3fbb..eb53bd7e535d6 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -679,10 +679,12 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
   bool haveFastClmul(Type *Ty) const override {
     // FIXME: clmul should really be Promote for any bitwidth under the largest
     // legal bitwidth for clmul. This is a hack to get around that shortcoming.
-    if (auto *IntTy = dyn_cast<IntegerType>(Ty))
-      if (Type *PromoteTy = DL.getSmallestLegalIntType(Ty->getContext(),
-                                                       IntTy->getBitWidth()))
-        Ty = PromoteTy;
+    auto *IntTy = dyn_cast<IntegerType>(Ty);
+    assert(IntTy && "Non-integer type");
+    if (Type *PromoteTy =
+            DL.getSmallestLegalIntType(Ty->getContext(), IntTy->getBitWidth()))
+      Ty = PromoteTy;
+
     const TargetLoweringBase *TLI = getTLI();
     EVT VT = TLI->getValueType(DL, Ty);
     return TLI->isOperationLegalOrCustomOrPromote(ISD::CLMUL, VT);
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index fd520f89cfb06..439d590910943 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -387,15 +387,16 @@ static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
   // Extend the divisor bit width to match the dividend.
   Divisor = Divisor.zext(Dividend.getBitWidth());
 
-  // The Poly argument should never be zero, or else this underflows.
-  auto Deg = [](const APInt &Poly) { return Poly.getActiveBits() - 1; };
+  // Note that getActiveBits(x) returns deg(x)+1, but the computation below
+  // still holds.
+  unsigned DivisorActiveBits = Divisor.getActiveBits();
 
   // Q = 0
   APInt Quotient = APInt::getZero(Dividend.getBitWidth());
   // S != 0 and deg(S) >= deg(P)
-  while (!Dividend.isZero() && Deg(Dividend) >= Deg(Divisor)) {
+  while (!Dividend.isZero() && Dividend.getActiveBits() >= DivisorActiveBits) {
     // T = S[deg(S)] / P[deg(P)]
-    unsigned Shift = Deg(Dividend) - Deg(Divisor);
+    unsigned Shift = Dividend.getActiveBits() - DivisorActiveBits;
     // Q = Q + T
     Quotient.setBit(Shift);
     // S = S - T * P
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index fa1b3b4e61874..19113a1fa3249 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -83,6 +83,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/InstructionCost.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/BuildLibCalls.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/LoopUtils.h"
@@ -1601,13 +1602,15 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // For the big-endian case, align the leftmost bit of the CRC with the
   // leftmost bit of the data which is used. For the little-endian case, align
   // the rightmost bits (nothing to do).
-  Value *CRCAlignTC = CRCExt;
-  if (Info.IsBigEndian) {
-    if (CRCBW > TC)
-      CRCAlignTC = Builder.CreateLShr(CRCAlignTC, CRCBW - TC, "crc.be.lshr");
-    else if (TC > CRCBW)
-      CRCAlignTC = Builder.CreateShl(CRCAlignTC, TC - CRCBW, "crc.be.shl");
-  }
+  Value *CRCAlignTC;
+  if (!Info.IsBigEndian)
+    CRCAlignTC = CRCExt;
+  else if (CRCBW > TC)
+    CRCAlignTC = Builder.CreateLShr(CRCExt, CRCBW - TC, "crc.be.lshr");
+  else if (TC > CRCBW)
+    CRCAlignTC = Builder.CreateShl(CRCExt, TC - CRCBW, "crc.be.shl");
+  else
+    CRCAlignTC = CRCExt;
 
   // If auxiliary data is present, XOR it in with the CRC.
   Value *ClmulMuInput = CRCAlignTC;
@@ -1668,9 +1671,21 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // Replace the result of the loop with the new computed CRC value.
   Info.ComputedValue->replaceUsesOutsideBlock(CRCNext, CurLoop->getLoopLatch());
 
-  // Get rid of the loop completely.
+  // Clean up the loop as much as possible so it can be trivially deleted.
   for (PHINode *PN : Cleanup)
     RecursivelyDeleteDeadPHINode(PN);
+  deleteDeadInstruction(CurLoop->getLatchCmpInst());
+  // Make the conditional branch always go to the exit block without changing
+  // the loop successors.
+  CondBrInst *BrInst =
+      cast<CondBrInst>(CurLoop->getLoopLatch()->getTerminator());
+  BasicBlock *ExitBlk = CurLoop->getExitBlock();
+  BasicBlock *OtherSucc = BrInst->getSuccessor(0);
+  if (OtherSucc == ExitBlk)
+    OtherSucc = BrInst->getSuccessor(1);
+  Builder.SetInsertPoint(BrInst);
+  Builder.CreateCondBr(ConstantInt::getBool(Ctx, true), ExitBlk, OtherSucc);
+  BrInst->eraseFromParent();
   SE->forgetLoop(CurLoop);
 
   return true;
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index c7f68e9cbc5ff..318642b5bca69 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -51,8 +51,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -118,8 +117,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -186,8 +184,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -252,8 +249,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -322,8 +318,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -384,8 +379,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -443,8 +437,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -523,8 +516,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; AES-NEXT:    br label %[[INNER_LOOP:.*]]
 ; AES:       [[INNER_LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; AES-NEXT:    br i1 true, label %[[INNER_EXIT]], label %[[INNER_LOOP]]
 ; AES:       [[INNER_EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; AES-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
@@ -608,8 +600,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
@@ -674,8 +665,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; AES-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 21bc6b3bf8c51..798ee2fb20a59 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -74,8 +74,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -187,8 +186,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -301,8 +299,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -415,8 +412,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -531,8 +527,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -641,8 +636,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -742,8 +736,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -864,8 +857,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; ZBC32-NEXT:    br label %[[INNER_LOOP:.*]]
 ; ZBC32:       [[INNER_LOOP]]:
-; ZBC32-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; ZBC32-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; ZBC32-NEXT:    br i1 true, label %[[INNER_EXIT]], label %[[INNER_LOOP]]
 ; ZBC32:       [[INNER_EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; ZBC32-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
@@ -1061,8 +1053,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; ZBC64-NEXT:    br label %[[LOOP:.*]]
 ; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC64:       [[EXIT]]:
 ; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
@@ -1149,8 +1140,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; ZBC64-NEXT:    br label %[[LOOP:.*]]
 ; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; ZBC64-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; ZBC64:       [[EXIT]]:
 ; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index 350cddd09cad4..77fc18395429d 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -51,8 +51,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -118,8 +117,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -186,8 +184,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -252,8 +249,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 15
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -322,8 +318,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -384,8 +379,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -443,8 +437,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -523,8 +516,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; PCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
 ; PCLMUL:       [[INNER_LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i32 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; PCLMUL-NEXT:    br i1 true, label %[[INNER_EXIT]], label %[[INNER_LOOP]]
 ; PCLMUL:       [[INNER_EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; PCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
@@ -608,8 +600,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
@@ -674,8 +665,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    [[EXIT_COND:%.*]] = icmp samesign ult i8 poison, 7
-; PCLMUL-NEXT:    br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]

>From 044545e00371682f0bdb3906379acdd969a95742 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Fri, 26 Jun 2026 13:54:55 -0500
Subject: [PATCH 12/18] Handle HashRecognize quirk rather than bailing, add
 test coverage for quirk

---
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  |  47 +-
 .../AArch64/cyclic-redundancy-check.ll        | 272 +++++++++-
 .../RISCV/cyclic-redundancy-check.ll          | 474 +++++++++++++++++-
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  | 272 +++++++++-
 .../LoopIdiom/cyclic-redundancy-check.ll      | 194 ++++++-
 5 files changed, 1228 insertions(+), 31 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 19113a1fa3249..9e336746498f3 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1565,15 +1565,6 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   unsigned ClmulBW = std::max(2 * TC, CRCBW + TC);
   Type *ClmulTy = IntegerType::get(Ctx, ClmulBW);
 
-  // For big-endian CRC loops where the auxiliary data is XORed with the CRC
-  // inside the loop, the bits won't be aligned properly if the bit widths don't
-  // match, and thus the CRC computation is incorrect, but HashRecognize will
-  // still detect the loop. Since this optimization always produces a correct
-  // CRC computation, bail in this edge case.
-  if (Info.IsBigEndian && Info.LHSAux &&
-      (TC != CRCBW || Info.LHSAux->getType()->getIntegerBitWidth() != CRCBW))
-    return false;
-
   // This optimization should only be applied if clmul for the required width is
   // a fast operation on the target.
   // TODO: If TC > CRCBW, then the data could probably be split into multiple
@@ -1616,20 +1607,34 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   Value *ClmulMuInput = CRCAlignTC;
   if (Value *Data = Info.LHSAux) {
     unsigned DataBW = Data->getType()->getIntegerBitWidth();
-    if (DataBW > TC) {
-      // Extract the useful bits of the data and discard the rest.
-      if (Info.IsBigEndian) {
-        Data = Builder.CreateLShr(Data, DataBW - TC, "data.be.lshr");
-      } else {
-        ConstantInt *Mask =
-            ConstantInt::get(Ctx, APInt::getLowBitsSet(DataBW, TC));
-        Data = Builder.CreateAnd(Data, Mask, "data.le.mask");
+    // For big-endian CRC loops where auxiliary data is XORed with the CRC
+    // inside the loop, the bits won't be aligned properly if the bit widths
+    // don't match, and thus the CRC computation is incorrect, but HashRecognize
+    // will still detect the loop. To handle the case where the data is zexted
+    // before XORing with the CRC, just ignore the auxiliary data entirely,
+    // because the extracted bit will always be zero.
+    if (!(Info.IsBigEndian && DataBW < CRCBW)) {
+      // For the aforementioned HashRecognize quirk, to handle the case where
+      // the data is truncated before XORing with the CRC, shift the data so the
+      // CRCBW-1 bit becomes the leftmost bit, and then the remaining logic
+      // treats the DataBW-1 bit as the first bit to be processed.
+      if (Info.IsBigEndian && DataBW > CRCBW)
+        Data = Builder.CreateShl(Data, DataBW - CRCBW, "data.be.shl");
+      if (DataBW > TC) {
+        // Extract the useful bits of the data and discard the rest.
+        if (Info.IsBigEndian) {
+          Data = Builder.CreateLShr(Data, DataBW - TC, "data.be.lshr");
+        } else {
+          ConstantInt *Mask =
+              ConstantInt::get(Ctx, APInt::getLowBitsSet(DataBW, TC));
+          Data = Builder.CreateAnd(Data, Mask, "data.le.mask");
+        }
       }
-    }
-    // This is always a zext since TripCount <= DataBW < ClmulBW.
-    Value *DataExt = Builder.CreateZExt(Data, ClmulTy, "data.ext");
+      // This is always a zext since TripCount <= DataBW < ClmulBW.
+      Value *DataExt = Builder.CreateZExt(Data, ClmulTy, "data.ext");
 
-    ClmulMuInput = Builder.CreateXor(CRCAlignTC, DataExt, "xor.crc.data");
+      ClmulMuInput = Builder.CreateXor(CRCAlignTC, DataExt, "xor.crc.data");
+    }
   }
 
   // Perform the first clmul operation with the mu/mu' constant. Input is TC
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index 318642b5bca69..0b1d9dc58e1b4 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -11,7 +11,11 @@
 ; NOAES: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOAES: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOAES: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; NOAES: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOAES: @.crctable.8 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOAES: @.crctable.9 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOAES: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOAES: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOAES: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOAES-LABEL: define i16 @crc16.le.tc8(
@@ -560,6 +564,270 @@ exit:                                              ; preds = %outer.loop
   ret i8 %crc.outer
 }
 
+define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
+; NOAES-LABEL: define i16 @crc16.be.tc16(
+; NOAES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOAES-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC_DATA_INDEXER]], 8
+; NOAES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.be.tc16(
+; AES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*:]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 69936)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i16 %xor.crc.data, 0
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
+; NOAES-LABEL: define i16 @crc16.be.tc8.misalign(
+; NOAES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = shl i8 [[MSG]], [[IV_BITS]]
+; NOAES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOAES-NEXT:    [[INDEXER_HI:%.*]] = lshr i8 [[CRC_DATA_INDEXER]], 8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.9, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOAES-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOAES-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i16 @crc16.be.tc8.misalign(
+; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*:]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %data.next = shl i8 %data, 1
+  %check.sb = icmp sge i8 %xor.data.crc, 0
+  %crc.shl = shl i16 %crc, 1
+  %xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
+; NOAES-LABEL: define i8 @crc8.be.tc16.misalign(
+; NOAES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOAES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOAES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.10, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i8 @crc8.be.tc16.misalign(
+; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*:]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_SHL]], [[DATA_EXT]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 72779)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 285)
+; AES-NEXT:    [[CRC_BE_SHL2:%.*]] = shl i32 [[CRC_EXT]], 16
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL2]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
+; NOAES-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; NOAES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOAES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOAES-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.11, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*:]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
+; AES-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; AES-NEXT:    [[DATA_BE_LSHR:%.*]] = lshr i16 [[DATA_BE_SHL]], 8
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_BE_LSHR]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 284)
+; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOAES-LABEL: define i32 @crc32.le.tc8.data32(
 ; NOAES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
@@ -574,7 +842,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
 ; NOAES-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
 ; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.12, i64 [[INDEXER_EXT]]
 ; NOAES-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
 ; NOAES-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
 ; NOAES-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 798ee2fb20a59..96c1232fc2808 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -13,7 +13,11 @@
 ; NOZBC32: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOZBC32: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOZBC32: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; NOZBC32: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOZBC32: @.crctable.8 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC32: @.crctable.9 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC32: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOZBC32: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOZBC32: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 ; ZBC32: @.crctable = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
@@ -25,7 +29,11 @@
 ; NOZBC64: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOZBC64: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOZBC64: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; NOZBC64: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOZBC64: @.crctable.8 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC64: @.crctable.9 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOZBC64: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOZBC64: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOZBC64: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 ; ZBC64: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
 ; ZBC64: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
@@ -35,6 +43,10 @@
 ; ZBC64: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; ZBC64: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; ZBC64: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; ZBC64: @.crctable.8 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; ZBC64: @.crctable.9 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; ZBC64: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; ZBC64: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOZBC32-LABEL: define i16 @crc16.le.tc8(
@@ -965,6 +977,460 @@ exit:                                              ; preds = %outer.loop
   ret i8 %crc.outer
 }
 
+define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
+; NOZBC32-LABEL: define i16 @crc16.be.tc16(
+; NOZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC_DATA_INDEXER]], 8
+; NOZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.8, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.be.tc16(
+; ZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*:]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 69936)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; NOZBC64-LABEL: define i16 @crc16.be.tc16(
+; NOZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC_DATA_INDEXER]], 8
+; NOZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.be.tc16(
+; ZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC_DATA_INDEXER]], 8
+; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i16 %xor.crc.data, 0
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
+; NOZBC32-LABEL: define i16 @crc16.be.tc8.misalign(
+; NOZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = shl i8 [[MSG]], [[IV_BITS]]
+; NOZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC32-NEXT:    [[INDEXER_HI:%.*]] = lshr i8 [[CRC_DATA_INDEXER]], 8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.9, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC32-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i16 @crc16.be.tc8.misalign(
+; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*:]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; NOZBC64-LABEL: define i16 @crc16.be.tc8.misalign(
+; NOZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i8 [[MSG]], [[IV_BITS]]
+; NOZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i8 [[CRC_DATA_INDEXER]], 8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.9, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i16 @crc16.be.tc8.misalign(
+; ZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i8 [[MSG]], [[IV_BITS]]
+; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i8 [[CRC_DATA_INDEXER]], 8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.9, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %data.next = shl i8 %data, 1
+  %check.sb = icmp sge i8 %xor.data.crc, 0
+  %crc.shl = shl i16 %crc, 1
+  %xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
+; NOZBC32-LABEL: define i8 @crc8.be.tc16.misalign(
+; NOZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.10, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i8 @crc8.be.tc16.misalign(
+; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*:]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
+; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_SHL]], [[DATA_EXT]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 72779)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 285)
+; ZBC32-NEXT:    [[CRC_BE_SHL2:%.*]] = shl i32 [[CRC_EXT]], 16
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL2]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; NOZBC64-LABEL: define i8 @crc8.be.tc16.misalign(
+; NOZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.10, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i8 @crc8.be.tc16.misalign(
+; ZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.10, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
+; NOZBC32-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; NOZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC32-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.11, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ZBC32-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*:]]
+; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
+; ZBC32-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; ZBC32-NEXT:    [[DATA_BE_LSHR:%.*]] = lshr i16 [[DATA_BE_SHL]], 8
+; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_BE_LSHR]]
+; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 284)
+; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; NOZBC64-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; NOZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.11, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ZBC64-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; ZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC64-NEXT:  [[ENTRY:.*]]:
+; ZBC64-NEXT:    br label %[[LOOP:.*]]
+; ZBC64:       [[LOOP]]:
+; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.11, i64 [[INDEXER_EXT]]
+; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC64:       [[EXIT]]:
+; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; ZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOZBC32-LABEL: define i32 @crc32.le.tc8.data32(
 ; NOZBC32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
@@ -979,7 +1445,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
 ; NOZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
 ; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.12, i32 [[INDEXER_EXT]]
 ; NOZBC32-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
 ; NOZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
 ; NOZBC32-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
@@ -1027,7 +1493,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
 ; NOZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
 ; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.12, i64 [[INDEXER_EXT]]
 ; NOZBC64-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
 ; NOZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
 ; NOZBC64-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index 77fc18395429d..e2f27aa14547d 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -11,7 +11,11 @@
 ; NOPCLMUL: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOPCLMUL: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; NOPCLMUL: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; NOPCLMUL: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOPCLMUL: @.crctable.8 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOPCLMUL: @.crctable.9 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; NOPCLMUL: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOPCLMUL: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; NOPCLMUL: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOPCLMUL-LABEL: define i16 @crc16.le.tc8(
@@ -560,6 +564,270 @@ exit:                                              ; preds = %outer.loop
   ret i8 %crc.outer
 }
 
+define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
+; NOPCLMUL-LABEL: define i16 @crc16.be.tc16(
+; NOPCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; NOPCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC_DATA_INDEXER]], 8
+; NOPCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.be.tc16(
+; PCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 69936)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i16 %xor.crc.data, 0
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
+; NOPCLMUL-LABEL: define i16 @crc16.be.tc8.misalign(
+; NOPCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = shl i8 [[MSG]], [[IV_BITS]]
+; NOPCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOPCLMUL-NEXT:    [[INDEXER_HI:%.*]] = lshr i8 [[CRC_DATA_INDEXER]], 8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.9, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; NOPCLMUL-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i16 @crc16.be.tc8.misalign(
+; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %data.next = shl i8 %data, 1
+  %check.sb = icmp sge i8 %xor.data.crc, 0
+  %crc.shl = shl i16 %crc, 1
+  %xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
+; NOPCLMUL-LABEL: define i8 @crc8.be.tc16.misalign(
+; NOPCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOPCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOPCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.10, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i8 @crc8.be.tc16.misalign(
+; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_SHL]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 72779)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 285)
+; PCLMUL-NEXT:    [[CRC_BE_SHL2:%.*]] = shl i32 [[CRC_EXT]], 16
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL2]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
+; NOPCLMUL-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; NOPCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; NOPCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOPCLMUL-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.11, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
+; PCLMUL-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; PCLMUL-NEXT:    [[DATA_BE_LSHR:%.*]] = lshr i16 [[DATA_BE_SHL]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_BE_LSHR]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 284)
+; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOPCLMUL-LABEL: define i32 @crc32.le.tc8.data32(
 ; NOPCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
@@ -574,7 +842,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
 ; NOPCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
 ; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.12, i64 [[INDEXER_EXT]]
 ; NOPCLMUL-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
 ; NOPCLMUL-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
 ; NOPCLMUL-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
diff --git a/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll
index 90995a0257721..2d40608a0440a 100644
--- a/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll
@@ -10,7 +10,11 @@
 ; CHECK: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; CHECK: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
 ; CHECK: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; CHECK: @.crctable.8 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; CHECK: @.crctable.8 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; CHECK: @.crctable.9 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
+; CHECK: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; CHECK: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; CHECK: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; CHECK-LABEL: define i16 @crc16.le.tc8(
@@ -394,6 +398,192 @@ exit:                                              ; preds = %outer.loop
   ret i8 %crc.outer
 }
 
+define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
+; CHECK-LABEL: define i16 @crc16.be.tc16(
+; CHECK-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; CHECK-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; CHECK-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; CHECK-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
+; CHECK-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC_DATA_INDEXER]], 8
+; CHECK-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
+; CHECK-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; CHECK-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; CHECK-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; CHECK-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; CHECK-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; CHECK-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; CHECK-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; CHECK-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i16 %xor.crc.data, 0
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
+; CHECK-LABEL: define i16 @crc16.be.tc8.misalign(
+; CHECK-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; CHECK-NEXT:    [[DATA_INDEXER:%.*]] = shl i8 [[MSG]], [[IV_BITS]]
+; CHECK-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
+; CHECK-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; CHECK-NEXT:    [[INDEXER_HI:%.*]] = lshr i8 [[CRC_DATA_INDEXER]], 8
+; CHECK-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI]] to i64
+; CHECK-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.9, i64 [[INDEXER_EXT]]
+; CHECK-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
+; CHECK-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
+; CHECK-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; CHECK-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; CHECK-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; CHECK-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %data.next = shl i8 %data, 1
+  %check.sb = icmp sge i8 %xor.data.crc, 0
+  %crc.shl = shl i16 %crc, 1
+  %xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
+; CHECK-LABEL: define i8 @crc8.be.tc16.misalign(
+; CHECK-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; CHECK-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; CHECK-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; CHECK-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; CHECK-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; CHECK-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; CHECK-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; CHECK-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.10, i64 [[INDEXER_EXT]]
+; CHECK-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; CHECK-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
+; CHECK-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; CHECK-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
+; CHECK-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; CHECK-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; CHECK-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
+; CHECK-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
+; CHECK-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
+; CHECK-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; CHECK-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
+; CHECK-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
+; CHECK-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.11, i64 [[INDEXER_EXT]]
+; CHECK-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; CHECK-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; CHECK-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; CHECK-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; CHECK-LABEL: define i32 @crc32.le.tc8.data32(
 ; CHECK-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) {
@@ -408,7 +598,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; CHECK-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
 ; CHECK-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
 ; CHECK-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; CHECK-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.8, i64 [[INDEXER_EXT]]
+; CHECK-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable.12, i64 [[INDEXER_EXT]]
 ; CHECK-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
 ; CHECK-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
 ; CHECK-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]

>From 96e68993081a862952955cffa2e0f480ad6526fd Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Fri, 26 Jun 2026 14:38:09 -0500
Subject: [PATCH 13/18] Add helper lambda

---
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 27 +++++++++----------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 9e336746498f3..7dbc3f2f71e05 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1588,6 +1588,16 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
 
   IRBuilder<> Builder(CurLoop->getLoopPreheader()->getTerminator());
 
+  auto GetMSBits = [&](Value *Op, unsigned BW, unsigned Count,
+                       const Twine &Name) {
+    unsigned OpBW = Op->getType()->getIntegerBitWidth();
+    assert(BW > Count && OpBW > Count);
+    if (Info.IsBigEndian)
+      return Builder.CreateLShr(Op, BW - Count, Name + ".be.lshr");
+    auto *Mask = ConstantInt::get(Ctx, APInt::getLowBitsSet(OpBW, Count));
+    return Builder.CreateAnd(Op, Mask, Name + ".le.mask");
+  };
+
   Value *CRCExt = Builder.CreateZExt(Info.LHS, ClmulTy, "crc.ext");
 
   // For the big-endian case, align the leftmost bit of the CRC with the
@@ -1622,13 +1632,7 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
         Data = Builder.CreateShl(Data, DataBW - CRCBW, "data.be.shl");
       if (DataBW > TC) {
         // Extract the useful bits of the data and discard the rest.
-        if (Info.IsBigEndian) {
-          Data = Builder.CreateLShr(Data, DataBW - TC, "data.be.lshr");
-        } else {
-          ConstantInt *Mask =
-              ConstantInt::get(Ctx, APInt::getLowBitsSet(DataBW, TC));
-          Data = Builder.CreateAnd(Data, Mask, "data.le.mask");
-        }
+        Data = GetMSBits(Data, DataBW, TC, "data");
       }
       // This is always a zext since TripCount <= DataBW < ClmulBW.
       Value *DataExt = Builder.CreateZExt(Data, ClmulTy, "data.ext");
@@ -1643,14 +1647,7 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
                                                  Mu, {}, "clmul.mu");
 
   // Extract the relevant bits from the result.
-  Value *ClmulGPInput;
-  if (Info.IsBigEndian) {
-    ClmulGPInput = Builder.CreateLShr(ClmulMu, TC, "quot.be.lshr");
-  } else {
-    ConstantInt *Mask =
-        ConstantInt::get(Ctx, APInt::getLowBitsSet(ClmulBW, TC));
-    ClmulGPInput = Builder.CreateAnd(ClmulMu, Mask, "quot.le.mask");
-  }
+  Value *ClmulGPInput = GetMSBits(ClmulMu, 2 * TC, TC, "quot");
 
   // Perform the second clmul operation with the P(x)/P(x)' constant. Input is
   // TC bits and GP is CRCBW+1 bits, so the result will be CRCBW+TC bits.

>From 9927f925fb8a3bf308b5e8214e4bb6e286ff5d2a Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Fri, 26 Jun 2026 15:55:35 -0500
Subject: [PATCH 14/18] Apply suggested changes

---
 llvm/include/llvm/Analysis/HashRecognize.h    |  34 +--
 .../llvm/Analysis/TargetTransformInfo.h       |   2 +-
 .../llvm/Analysis/TargetTransformInfoImpl.h   |   2 +-
 llvm/include/llvm/CodeGen/BasicTTIImpl.h      |   8 +-
 llvm/lib/Analysis/HashRecognize.cpp           |  34 ++-
 llvm/lib/Analysis/TargetTransformInfo.cpp     |   2 +-
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  | 112 +++++-----
 .../HashRecognize/cyclic-redundancy-check.ll  | 195 ++++++++++++++++++
 .../AArch64/cyclic-redundancy-check.ll        |  28 +--
 .../RISCV/cyclic-redundancy-check.ll          |  28 +--
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  |  28 +--
 11 files changed, 320 insertions(+), 153 deletions(-)

diff --git a/llvm/include/llvm/Analysis/HashRecognize.h b/llvm/include/llvm/Analysis/HashRecognize.h
index 1ab3fe6b31c9b..221e8f871b9fc 100644
--- a/llvm/include/llvm/Analysis/HashRecognize.h
+++ b/llvm/include/llvm/Analysis/HashRecognize.h
@@ -35,31 +35,6 @@ struct CRCTable : public std::array<APInt, 256> {
 #endif
 };
 
-/// The constants used to perform a Polynomial (GF(2)) Barrett Reduction as
-/// roughly specified in Intel's Fast CRC Computation white paper
-/// (https://www.researchgate.net/publication/263424619_Fast_CRC_computation).
-/// Both constants are bit-reflected across their respective widths for
-/// bit-reflected CRCs.
-struct CRCBarrettConstants {
-  // The constant used in the first clmul operation, which is mu =
-  // floor(x^(CRCBW+DataBW) / P(x)). Bit width is DataBW+1.
-  APInt Mu;
-
-  // The constant used in the second clmul operation, which is the generating
-  // polynomial P(x) with the implied x^CRCBW term included. Bit width is
-  // CRCBW+1.
-  APInt FullGenPoly;
-
-  CRCBarrettConstants(const APInt &Mu, const APInt &FullGenPoly)
-      : Mu(Mu), FullGenPoly(FullGenPoly) {}
-
-  LLVM_ABI void print(raw_ostream &OS) const;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  LLVM_ABI LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
 /// The structure that is returned when a polynomial algorithm was recognized by
 /// the analysis. Currently, only the CRC algorithm is recognized.
 struct PolynomialInfo {
@@ -115,7 +90,14 @@ class HashRecognize {
 
   // Auxilary entry point after analysis to generate constants for a GF(2)
   // Barrett Reduction.
-  LLVM_ABI static CRCBarrettConstants
+  // The first APInt is the constant used in the first clmul operation, which is
+  // mu = floor(x^(BW+TC) / P(x)); bit width is TC+1.
+  // The second APInt is the constant used in the second clmul operation, which
+  // is the generating polynomial P(x) with the implied x^BW term included; bit
+  // width is BW+1.
+  // Both constants are bit-reflected across their respective
+  // widths for bit-reflected CRCs.
+  LLVM_ABI static std::pair<APInt, APInt>
   genBarrettConstants(const APInt &GenPoly, unsigned TripCount,
                       bool ByteOrderSwapped);
 
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index d6ce82219ad12..0b228a682aeb1 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1187,7 +1187,7 @@ class TargetTransformInfo {
 
   /// Return true if the hardware has a fast carryless-multiplication
   /// instruction.
-  LLVM_ABI bool haveFastClmul(Type *Ty) const;
+  LLVM_ABI bool haveFastClmul(IntegerType *Ty) const;
 
   /// Return true if the cost of the instruction is too high to speculatively
   /// execute and should be kept behind a branch.
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index a60e7e9a85508..25574a2d2c0e5 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -570,7 +570,7 @@ class LLVM_ABI TargetTransformInfoImplBase {
 
   virtual bool haveFastSqrt(Type *Ty) const { return false; }
 
-  virtual bool haveFastClmul(Type *Ty) const { return false; }
+  virtual bool haveFastClmul(IntegerType *Ty) const { return false; }
 
   virtual bool isExpensiveToSpeculativelyExecute(const Instruction *I) const {
     return true;
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index eb53bd7e535d6..36e62ddc4c237 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -676,13 +676,11 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
            TLI->isOperationLegalOrCustom(ISD::FSQRT, VT);
   }
 
-  bool haveFastClmul(Type *Ty) const override {
+  bool haveFastClmul(IntegerType *Ty) const override {
     // FIXME: clmul should really be Promote for any bitwidth under the largest
     // legal bitwidth for clmul. This is a hack to get around that shortcoming.
-    auto *IntTy = dyn_cast<IntegerType>(Ty);
-    assert(IntTy && "Non-integer type");
-    if (Type *PromoteTy =
-            DL.getSmallestLegalIntType(Ty->getContext(), IntTy->getBitWidth()))
+    if (auto *PromoteTy = dyn_cast_if_present<IntegerType>(
+            DL.getSmallestLegalIntType(Ty->getContext(), Ty->getBitWidth())))
       Ty = PromoteTy;
 
     const TargetLoweringBase *TLI = getTLI();
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index 439d590910943..e17c03ad35a84 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -379,8 +379,9 @@ CRCTable HashRecognize::genSarwateTable(const APInt &GenPoly,
 // Perform polynomial (GF(2)) floor division. This is based on the
 // floor_division(S, P) algorithm in
 // https://www.corsix.org/content/barrett-reduction-polynomials. Note that the
-// maximum degree of the returned polynomial is max(0, deg(Dividend) -
-// deg(Divisor)), but the bit width will be the same as that of Dividend.
+// maximum degree of the returned polynomial is
+// max(0, deg(Dividend) - deg(Divisor)), but the bit width will be the same as
+// that of Dividend.
 static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
   assert(!Divisor.isZero() && "Cannot divide by zero");
 
@@ -407,12 +408,12 @@ static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
 
 // Generate the constants for performing a Polynomial (GF(2)) Barrett Reduction
 // according to Intel's Fast CRC Computation white paper
-// (https://www.researchgate.net/publication/263424619_Fast_CRC_computation),
+// (https://web.archive.org/web/20131224125630/https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf),
 // with some adjustments to account for the fact that bit width and trip count
 // can vary.
-CRCBarrettConstants HashRecognize::genBarrettConstants(const APInt &GenPoly,
-                                                       unsigned TripCount,
-                                                       bool IsBigEndian) {
+std::pair<APInt, APInt>
+HashRecognize::genBarrettConstants(const APInt &GenPoly, unsigned TripCount,
+                                   bool IsBigEndian) {
   unsigned BW = GenPoly.getBitWidth();
 
   // Recover the full generating polynomial in normal form by reflecting the LE
@@ -598,18 +599,6 @@ void CRCTable::print(raw_ostream &OS) const {
 void CRCTable::dump() const { print(dbgs()); }
 #endif
 
-void CRCBarrettConstants::print(raw_ostream &OS) const {
-  OS << "Mu = ";
-  Mu.print(OS, false);
-  OS << ", FullGenPoly = ";
-  FullGenPoly.print(OS, false);
-  OS << '\n';
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void CRCBarrettConstants::dump() const { print(dbgs()); }
-#endif
-
 void HashRecognize::print(raw_ostream &OS) const {
   if (!L.isInnermost())
     return;
@@ -645,8 +634,13 @@ void HashRecognize::print(raw_ostream &OS) const {
   OS.indent(2) << "Computed CRC lookup table:\n";
   genSarwateTable(Info.RHS, Info.IsBigEndian).print(OS);
   OS.indent(2) << "Computed CRC Barrett constants:\n";
-  genBarrettConstants(Info.RHS, Info.TripCount, Info.IsBigEndian)
-      .print(OS);
+  auto [Mu, FullGenPoly] =
+      genBarrettConstants(Info.RHS, Info.TripCount, Info.IsBigEndian);
+  OS << "Mu = ";
+  Mu.print(OS, false);
+  OS << ", FullGenPoly = ";
+  FullGenPoly.print(OS, false);
+  OS << '\n';
 }
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 02a9a865ddc88..dcb1c292e0211 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -743,7 +743,7 @@ bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
   return TTIImpl->haveFastSqrt(Ty);
 }
 
-bool TargetTransformInfo::haveFastClmul(Type *Ty) const {
+bool TargetTransformInfo::haveFastClmul(IntegerType *Ty) const {
   return TTIImpl->haveFastClmul(Ty);
 }
 
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 7dbc3f2f71e05..a63d9bb9907e1 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -259,8 +259,8 @@ class LoopIdiomRecognize {
                                   const SCEV *BECount);
   bool avoidLIRForMultiBlockLoop(bool IsMemset = false,
                                  bool IsLoopMemset = false);
-  bool optimizeCRCLoopToClmul(const PolynomialInfo &Info);
-  bool optimizeCRCLoopToLookup(const PolynomialInfo &Info);
+  bool optimizeCRCLoopUsingClmul(const PolynomialInfo &Info);
+  bool optimizeCRCLoopUsingTableLookup(const PolynomialInfo &Info);
 
   /// @}
   /// \name Noncountable Loop Idiom Handling
@@ -403,8 +403,9 @@ bool LoopIdiomRecognize::runOnCountableLoop() {
   // table if we're optimizing for size.
   if (!DisableLIRP::HashRecognize)
     if (auto Res = HashRecognize(*CurLoop, *SE).getResult())
-      MadeChange |= optimizeCRCLoopToClmul(*Res) ||
-                    (!ApplyCodeSizeHeuristics && optimizeCRCLoopToLookup(*Res));
+      MadeChange |=
+          optimizeCRCLoopUsingClmul(*Res) ||
+          (!ApplyCodeSizeHeuristics && optimizeCRCLoopUsingTableLookup(*Res));
 
   return MadeChange;
 }
@@ -1552,7 +1553,7 @@ bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
   return false;
 }
 
-bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
+bool LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info) {
   Type *CRCTy = Info.LHS->getType();
   LLVMContext &Ctx = CRCTy->getContext();
   unsigned CRCBW = CRCTy->getIntegerBitWidth();
@@ -1563,7 +1564,7 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // The first clmul uses 2*TC bits, and the second clmul uses CRCBW+TC bits.
   // For simplicity, have both operate on the same bit width.
   unsigned ClmulBW = std::max(2 * TC, CRCBW + TC);
-  Type *ClmulTy = IntegerType::get(Ctx, ClmulBW);
+  auto *ClmulTy = IntegerType::get(Ctx, ClmulBW);
 
   // This optimization should only be applied if clmul for the required width is
   // a fast operation on the target.
@@ -1573,45 +1574,35 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
     return false;
 
   // First, generate the constants required for GF(2) Barrett reduction.
-  CRCBarrettConstants Constants =
+  auto [Mu, FullGenPoly] =
       HashRecognize::genBarrettConstants(Info.RHS, TC, Info.IsBigEndian);
-  Value *Mu = ConstantInt::get(Ctx, Constants.Mu.zext(ClmulBW));
-  Value *FullGenPoly =
-      ConstantInt::get(Ctx, Constants.FullGenPoly.zext(ClmulBW));
-
-  // Mark all PHIs for removal since we're getting rid of the loop.
-  SmallVector<PHINode *, 2> Cleanup;
-  for (PHINode &PN : CurLoop->getHeader()->phis()) {
-    PN.replaceAllUsesWith(PoisonValue::get(PN.getType()));
-    Cleanup.push_back(&PN);
-  }
+  Value *MuExt = ConstantInt::get(Ctx, Mu.zext(ClmulBW));
+  Value *FullGenPolyExt = ConstantInt::get(Ctx, FullGenPoly.zext(ClmulBW));
 
   IRBuilder<> Builder(CurLoop->getLoopPreheader()->getTerminator());
 
-  auto GetMSBits = [&](Value *Op, unsigned BW, unsigned Count,
-                       const Twine &Name) {
+  auto GetMostSignificantTCBits = [&, TC](Value *Op, unsigned BW,
+                                          const Twine &Name) {
     unsigned OpBW = Op->getType()->getIntegerBitWidth();
-    assert(BW > Count && OpBW > Count);
+    assert(BW > TC && OpBW > TC);
     if (Info.IsBigEndian)
-      return Builder.CreateLShr(Op, BW - Count, Name + ".be.lshr");
-    auto *Mask = ConstantInt::get(Ctx, APInt::getLowBitsSet(OpBW, Count));
+      return Builder.CreateLShr(Op, BW - TC, Name + ".be.lshr");
+    auto *Mask = ConstantInt::get(Ctx, APInt::getLowBitsSet(OpBW, TC));
     return Builder.CreateAnd(Op, Mask, Name + ".le.mask");
   };
 
-  Value *CRCExt = Builder.CreateZExt(Info.LHS, ClmulTy, "crc.ext");
+  Value *LHS = Builder.CreateZExt(Info.LHS, ClmulTy, "crc.ext");
 
   // For the big-endian case, align the leftmost bit of the CRC with the
   // leftmost bit of the data which is used. For the little-endian case, align
   // the rightmost bits (nothing to do).
   Value *CRCAlignTC;
-  if (!Info.IsBigEndian)
-    CRCAlignTC = CRCExt;
+  if (!Info.IsBigEndian || CRCBW == TC)
+    CRCAlignTC = LHS;
   else if (CRCBW > TC)
-    CRCAlignTC = Builder.CreateLShr(CRCExt, CRCBW - TC, "crc.be.lshr");
-  else if (TC > CRCBW)
-    CRCAlignTC = Builder.CreateShl(CRCExt, TC - CRCBW, "crc.be.shl");
+    CRCAlignTC = Builder.CreateLShr(LHS, CRCBW - TC, "crc.be.lshr");
   else
-    CRCAlignTC = CRCExt;
+    CRCAlignTC = Builder.CreateShl(LHS, TC - CRCBW, "crc.be.shl");
 
   // If auxiliary data is present, XOR it in with the CRC.
   Value *ClmulMuInput = CRCAlignTC;
@@ -1623,7 +1614,7 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
     // will still detect the loop. To handle the case where the data is zexted
     // before XORing with the CRC, just ignore the auxiliary data entirely,
     // because the extracted bit will always be zero.
-    if (!(Info.IsBigEndian && DataBW < CRCBW)) {
+    if (!Info.IsBigEndian || DataBW >= CRCBW) {
       // For the aforementioned HashRecognize quirk, to handle the case where
       // the data is truncated before XORing with the CRC, shift the data so the
       // CRCBW-1 bit becomes the leftmost bit, and then the remaining logic
@@ -1632,34 +1623,34 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
         Data = Builder.CreateShl(Data, DataBW - CRCBW, "data.be.shl");
       if (DataBW > TC) {
         // Extract the useful bits of the data and discard the rest.
-        Data = GetMSBits(Data, DataBW, TC, "data");
+        Data = GetMostSignificantTCBits(Data, DataBW, "data");
       }
       // This is always a zext since TripCount <= DataBW < ClmulBW.
-      Value *DataExt = Builder.CreateZExt(Data, ClmulTy, "data.ext");
+      Data = Builder.CreateZExt(Data, ClmulTy, "data.ext");
 
-      ClmulMuInput = Builder.CreateXor(CRCAlignTC, DataExt, "xor.crc.data");
+      ClmulMuInput = Builder.CreateXor(CRCAlignTC, Data, "xor.crc.data");
     }
   }
 
   // Perform the first clmul operation with the mu/mu' constant. Input is TC
   // bits and Mu is TC+1 bits, so the result will be 2*TC bits.
-  Value *ClmulMu = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulMuInput,
-                                                 Mu, {}, "clmul.mu");
+  Value *ClmulMu = Builder.CreateBinaryIntrinsic(
+      Intrinsic::clmul, ClmulMuInput, MuExt, /*FMFSource=*/{}, "clmul.mu");
 
   // Extract the relevant bits from the result.
-  Value *ClmulGPInput = GetMSBits(ClmulMu, 2 * TC, TC, "quot");
+  Value *ClmulGPInput = GetMostSignificantTCBits(ClmulMu, 2 * TC, "quot");
 
   // Perform the second clmul operation with the P(x)/P(x)' constant. Input is
   // TC bits and GP is CRCBW+1 bits, so the result will be CRCBW+TC bits.
   Value *ClmulGP = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulGPInput,
-                                                 FullGenPoly, {}, "clmul.gp");
+                                                 FullGenPolyExt,
+                                                 /*FMFSource=*/{}, "clmul.gp");
 
   // For the big-endian case, align the leftmost bit of the CRC with the
   // leftmost bit of the clmul result. For the little-endian case, align the
   // rightmost bits (nothing to do).
-  Value *CRCAlignClmul = CRCExt;
-  if (Info.IsBigEndian)
-    CRCAlignClmul = Builder.CreateShl(CRCExt, TC, "crc.be.shl");
+  Value *CRCAlignClmul =
+      Info.IsBigEndian ? Builder.CreateShl(LHS, TC, "crc.be.shl") : LHS;
 
   // Get the remainder by subtracting (XORing) the calculated multiple of
   // GenPoly from the CRC.
@@ -1673,27 +1664,34 @@ bool LoopIdiomRecognize::optimizeCRCLoopToClmul(const PolynomialInfo &Info) {
   // Replace the result of the loop with the new computed CRC value.
   Info.ComputedValue->replaceUsesOutsideBlock(CRCNext, CurLoop->getLoopLatch());
 
-  // Clean up the loop as much as possible so it can be trivially deleted.
-  for (PHINode *PN : Cleanup)
-    RecursivelyDeleteDeadPHINode(PN);
-  deleteDeadInstruction(CurLoop->getLatchCmpInst());
-  // Make the conditional branch always go to the exit block without changing
-  // the loop successors.
-  CondBrInst *BrInst =
-      cast<CondBrInst>(CurLoop->getLoopLatch()->getTerminator());
-  BasicBlock *ExitBlk = CurLoop->getExitBlock();
-  BasicBlock *OtherSucc = BrInst->getSuccessor(0);
-  if (OtherSucc == ExitBlk)
-    OtherSucc = BrInst->getSuccessor(1);
-  Builder.SetInsertPoint(BrInst);
-  Builder.CreateCondBr(ConstantInt::getBool(Ctx, true), ExitBlk, OtherSucc);
-  BrInst->eraseFromParent();
-  SE->forgetLoop(CurLoop);
+  // Finally, clean up the loop as much as possible so it can be trivially
+  // deleted.
+  {
+    // Add the loop PHI nodes to a worklist since deleting a PHI invalidates the
+    // iterator.
+    SmallVector<PHINode *, 3> LoopPHIs;
+    for (PHINode &PN : CurLoop->getHeader()->phis()) {
+      PN.replaceAllUsesWith(PoisonValue::get(PN.getType()));
+      LoopPHIs.push_back(&PN);
+    }
+    for (PHINode *PN : LoopPHIs) {
+      RecursivelyDeleteDeadPHINode(PN);
+    }
+    // Replace the exit condition with constant true/false to always cause a
+    // branch to the exit block.
+    deleteDeadInstruction(CurLoop->getLatchCmpInst());
+    CondBrInst *BrInst =
+        cast<CondBrInst>(CurLoop->getLoopLatch()->getTerminator());
+    bool BrToExitCond = BrInst->getSuccessor(0) == CurLoop->getExitBlock();
+    BrInst->setCondition(ConstantInt::getBool(Ctx, BrToExitCond));
+    SE->forgetLoop(CurLoop);
+  }
 
   return true;
 }
 
-bool LoopIdiomRecognize::optimizeCRCLoopToLookup(const PolynomialInfo &Info) {
+bool LoopIdiomRecognize::optimizeCRCLoopUsingTableLookup(
+    const PolynomialInfo &Info) {
   // FIXME: Hexagon has a special HexagonLoopIdiom that optimizes CRC using
   // carry-less multiplication instructions, which is more efficient than our
   // Sarwate table-lookup optimization. Hence, until we're able to emit
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index fe404e76812e1..c51ecfea886b8 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -396,6 +396,201 @@ exit:                                              ; preds = %outer.loop
   ret i8 %crc.outer
 }
 
+define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
+; CHECK-LABEL: 'crc16.be.tc16'
+; CHECK-NEXT:  Found big-endian CRC-16 loop with trip count 16
+; CHECK-NEXT:    Initial CRC: i16 %checksum
+; CHECK-NEXT:    Generating polynomial: 4129
+; CHECK-NEXT:    Computed CRC: %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+; CHECK-NEXT:    Auxiliary data: i16 %msg
+; CHECK-NEXT:    Computed CRC lookup table:
+; CHECK-NEXT:  0 4129 8258 12387 16516 20645 24774 28903 33032 37161 41290 45419 49548 53677 57806 61935
+; CHECK-NEXT:  4657 528 12915 8786 21173 17044 29431 25302 37689 33560 45947 41818 54205 50076 62463 58334
+; CHECK-NEXT:  9314 13379 1056 5121 25830 29895 17572 21637 42346 46411 34088 38153 58862 62927 50604 54669
+; CHECK-NEXT:  13907 9842 5649 1584 30423 26358 22165 18100 46939 42874 38681 34616 63455 59390 55197 51132
+; CHECK-NEXT:  18628 22757 26758 30887 2112 6241 10242 14371 51660 55789 59790 63919 35144 39273 43274 47403
+; CHECK-NEXT:  23285 19156 31415 27286 6769 2640 14899 10770 56317 52188 64447 60318 39801 35672 47931 43802
+; CHECK-NEXT:  27814 31879 19684 23749 11298 15363 3168 7233 60846 64911 52716 56781 44330 48395 36200 40265
+; CHECK-NEXT:  32407 28342 24277 20212 15891 11826 7761 3696 65439 61374 57309 53244 48923 44858 40793 36728
+; CHECK-NEXT:  37256 33193 45514 41451 53516 49453 61774 57711 4224 161 12482 8419 20484 16421 28742 24679
+; CHECK-NEXT:  33721 37784 41979 46042 49981 54044 58239 62302 689 4752 8947 13010 16949 21012 25207 29270
+; CHECK-NEXT:  46570 42443 38312 34185 62830 58703 54572 50445 13538 9411 5280 1153 29798 25671 21540 17413
+; CHECK-NEXT:  42971 47098 34713 38840 59231 63358 50973 55100 9939 14066 1681 5808 26199 30326 17941 22068
+; CHECK-NEXT:  55628 51565 63758 59695 39368 35305 47498 43435 22596 18533 30726 26663 6336 2273 14466 10403
+; CHECK-NEXT:  52093 56156 60223 64286 35833 39896 43963 48026 19061 23124 27191 31254 2801 6864 10931 14994
+; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
+; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Mu = 69936, FullGenPoly = 69665
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %xor.crc.data = xor i16 %crc, %data
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i16 %xor.crc.data, 0
+  %crc.shl = shl i16 %crc, 1
+  %crc.xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
+; CHECK-LABEL: 'crc16.be.tc8.misalign'
+; CHECK-NEXT:  Found big-endian CRC-16 loop with trip count 8
+; CHECK-NEXT:    Initial CRC: i16 %checksum
+; CHECK-NEXT:    Generating polynomial: 4129
+; CHECK-NEXT:    Computed CRC: %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
+; CHECK-NEXT:    Auxiliary data: i8 %msg
+; CHECK-NEXT:    Computed CRC lookup table:
+; CHECK-NEXT:  0 4129 8258 12387 16516 20645 24774 28903 33032 37161 41290 45419 49548 53677 57806 61935
+; CHECK-NEXT:  4657 528 12915 8786 21173 17044 29431 25302 37689 33560 45947 41818 54205 50076 62463 58334
+; CHECK-NEXT:  9314 13379 1056 5121 25830 29895 17572 21637 42346 46411 34088 38153 58862 62927 50604 54669
+; CHECK-NEXT:  13907 9842 5649 1584 30423 26358 22165 18100 46939 42874 38681 34616 63455 59390 55197 51132
+; CHECK-NEXT:  18628 22757 26758 30887 2112 6241 10242 14371 51660 55789 59790 63919 35144 39273 43274 47403
+; CHECK-NEXT:  23285 19156 31415 27286 6769 2640 14899 10770 56317 52188 64447 60318 39801 35672 47931 43802
+; CHECK-NEXT:  27814 31879 19684 23749 11298 15363 3168 7233 60846 64911 52716 56781 44330 48395 36200 40265
+; CHECK-NEXT:  32407 28342 24277 20212 15891 11826 7761 3696 65439 61374 57309 53244 48923 44858 40793 36728
+; CHECK-NEXT:  37256 33193 45514 41451 53516 49453 61774 57711 4224 161 12482 8419 20484 16421 28742 24679
+; CHECK-NEXT:  33721 37784 41979 46042 49981 54044 58239 62302 689 4752 8947 13010 16949 21012 25207 29270
+; CHECK-NEXT:  46570 42443 38312 34185 62830 58703 54572 50445 13538 9411 5280 1153 29798 25671 21540 17413
+; CHECK-NEXT:  42971 47098 34713 38840 59231 63358 50973 55100 9939 14066 1681 5808 26199 30326 17941 22068
+; CHECK-NEXT:  55628 51565 63758 59695 39368 35305 47498 43435 22596 18533 30726 26663 6336 2273 14466 10403
+; CHECK-NEXT:  52093 56156 60223 64286 35833 39896 43963 48026 19061 23124 27191 31254 2801 6864 10931 14994
+; CHECK-NEXT:  64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
+; CHECK-NEXT:  61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Mu = 273, FullGenPoly = 69665
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
+  %crc.trunc = trunc i16 %crc to i8
+  %xor.data.crc = xor i8 %data, %crc.trunc
+  %data.next = shl i8 %data, 1
+  %check.sb = icmp sge i8 %xor.data.crc, 0
+  %crc.shl = shl i16 %crc, 1
+  %xor = xor i16 %crc.shl, 4129
+  %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i16 %crc.next
+}
+
+define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
+; CHECK-LABEL: 'crc8.be.tc16.misalign'
+; CHECK-NEXT:  Found big-endian CRC-8 loop with trip count 16
+; CHECK-NEXT:    Initial CRC: i8 %checksum
+; CHECK-NEXT:    Generating polynomial: 29
+; CHECK-NEXT:    Computed CRC: %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+; CHECK-NEXT:    Auxiliary data: i16 %msg
+; CHECK-NEXT:    Computed CRC lookup table:
+; CHECK-NEXT:  0 29 58 39 116 105 78 83 232 245 210 207 156 129 166 187
+; CHECK-NEXT:  205 208 247 234 185 164 131 158 37 56 31 2 81 76 107 118
+; CHECK-NEXT:  135 154 189 160 243 238 201 212 111 114 85 72 27 6 33 60
+; CHECK-NEXT:  74 87 112 109 62 35 4 25 162 191 152 133 214 203 236 241
+; CHECK-NEXT:  19 14 41 52 103 122 93 64 251 230 193 220 143 146 181 168
+; CHECK-NEXT:  222 195 228 249 170 183 144 141 54 43 12 17 66 95 120 101
+; CHECK-NEXT:  148 137 174 179 224 253 218 199 124 97 70 91 8 21 50 47
+; CHECK-NEXT:  89 68 99 126 45 48 23 10 177 172 139 150 197 216 255 226
+; CHECK-NEXT:  38 59 28 1 82 79 104 117 206 211 244 233 186 167 128 157
+; CHECK-NEXT:  235 246 209 204 159 130 165 184 3 30 57 36 119 106 77 80
+; CHECK-NEXT:  161 188 155 134 213 200 239 242 73 84 115 110 61 32 7 26
+; CHECK-NEXT:  108 113 86 75 24 5 34 63 132 153 190 163 240 237 202 215
+; CHECK-NEXT:  53 40 15 18 65 92 123 102 221 192 231 250 169 180 147 142
+; CHECK-NEXT:  248 229 194 223 140 145 182 171 16 13 42 55 100 121 94 67
+; CHECK-NEXT:  178 175 136 149 198 219 252 225 90 71 96 125 46 51 20 9
+; CHECK-NEXT:  127 98 69 88 11 22 49 44 151 138 173 176 227 254 217 196
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Mu = 72779, FullGenPoly = 285
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 15
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
+define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
+; CHECK-LABEL: 'crc8.be.tc8.data16.misalign'
+; CHECK-NEXT:  Found big-endian CRC-8 loop with trip count 8
+; CHECK-NEXT:    Initial CRC: i8 %checksum
+; CHECK-NEXT:    Generating polynomial: 29
+; CHECK-NEXT:    Computed CRC: %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+; CHECK-NEXT:    Auxiliary data: i16 %msg
+; CHECK-NEXT:    Computed CRC lookup table:
+; CHECK-NEXT:  0 29 58 39 116 105 78 83 232 245 210 207 156 129 166 187
+; CHECK-NEXT:  205 208 247 234 185 164 131 158 37 56 31 2 81 76 107 118
+; CHECK-NEXT:  135 154 189 160 243 238 201 212 111 114 85 72 27 6 33 60
+; CHECK-NEXT:  74 87 112 109 62 35 4 25 162 191 152 133 214 203 236 241
+; CHECK-NEXT:  19 14 41 52 103 122 93 64 251 230 193 220 143 146 181 168
+; CHECK-NEXT:  222 195 228 249 170 183 144 141 54 43 12 17 66 95 120 101
+; CHECK-NEXT:  148 137 174 179 224 253 218 199 124 97 70 91 8 21 50 47
+; CHECK-NEXT:  89 68 99 126 45 48 23 10 177 172 139 150 197 216 255 226
+; CHECK-NEXT:  38 59 28 1 82 79 104 117 206 211 244 233 186 167 128 157
+; CHECK-NEXT:  235 246 209 204 159 130 165 184 3 30 57 36 119 106 77 80
+; CHECK-NEXT:  161 188 155 134 213 200 239 242 73 84 115 110 61 32 7 26
+; CHECK-NEXT:  108 113 86 75 24 5 34 63 132 153 190 163 240 237 202 215
+; CHECK-NEXT:  53 40 15 18 65 92 123 102 221 192 231 250 169 180 147 142
+; CHECK-NEXT:  248 229 194 223 140 145 182 171 16 13 42 55 100 121 94 67
+; CHECK-NEXT:  178 175 136 149 198 219 252 225 90 71 96 125 46 51 20 9
+; CHECK-NEXT:  127 98 69 88 11 22 49 44 151 138 173 176 227 254 217 196
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Mu = 284, FullGenPoly = 285
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
+  %data.trunc = trunc i16 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %data.next = shl i16 %data, 1
+  %check.sb = icmp sge i8 %xor.crc.data, 0
+  %crc.shl = shl i8 %crc, 1
+  %crc.xor = xor i8 %crc.shl, 29
+  %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; CHECK-LABEL: 'crc32.le.tc8.data32'
 ; CHECK-NEXT:  Found little-endian CRC-32 loop with trip count 8
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index 0b1d9dc58e1b4..85696cbad83aa 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -55,7 +55,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -121,7 +121,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -188,7 +188,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -253,7 +253,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -322,7 +322,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -383,7 +383,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -441,7 +441,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -520,7 +520,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; AES-NEXT:    br label %[[INNER_LOOP:.*]]
 ; AES:       [[INNER_LOOP]]:
-; AES-NEXT:    br i1 true, label %[[INNER_EXIT]], label %[[INNER_LOOP]]
+; AES-NEXT:    br i1 false, label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; AES:       [[INNER_EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; AES-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
@@ -604,7 +604,7 @@ define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -668,7 +668,7 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; AES-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -735,7 +735,7 @@ define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -801,7 +801,7 @@ define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -868,7 +868,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
@@ -933,7 +933,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
-; AES-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
 ; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 96c1232fc2808..03ee5660c2c13 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -86,7 +86,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -198,7 +198,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -311,7 +311,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -424,7 +424,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -539,7 +539,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -648,7 +648,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -748,7 +748,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -869,7 +869,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; ZBC32-NEXT:    br label %[[INNER_LOOP:.*]]
 ; ZBC32:       [[INNER_LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[INNER_EXIT]], label %[[INNER_LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; ZBC32:       [[INNER_EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; ZBC32-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
@@ -1017,7 +1017,7 @@ define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -1131,7 +1131,7 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -1246,7 +1246,7 @@ define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -1358,7 +1358,7 @@ define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
 ; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; ZBC32-NEXT:    br label %[[LOOP:.*]]
 ; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC32:       [[EXIT]]:
 ; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -1519,7 +1519,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; ZBC64-NEXT:    br label %[[LOOP:.*]]
 ; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC64-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC64:       [[EXIT]]:
 ; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
@@ -1606,7 +1606,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; ZBC64-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; ZBC64-NEXT:    br label %[[LOOP:.*]]
 ; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; ZBC64-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; ZBC64:       [[EXIT]]:
 ; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; ZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index e2f27aa14547d..1c84a2b71ee80 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -55,7 +55,7 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -121,7 +121,7 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -188,7 +188,7 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -253,7 +253,7 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -322,7 +322,7 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -383,7 +383,7 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -441,7 +441,7 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -520,7 +520,7 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; PCLMUL-NEXT:    br label %[[INNER_LOOP:.*]]
 ; PCLMUL:       [[INNER_LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[INNER_EXIT]], label %[[INNER_LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[INNER_LOOP]], label %[[INNER_EXIT]]
 ; PCLMUL:       [[INNER_EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
 ; PCLMUL-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
@@ -604,7 +604,7 @@ define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -668,7 +668,7 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
@@ -735,7 +735,7 @@ define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -801,7 +801,7 @@ define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
@@ -868,7 +868,7 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
@@ -933,7 +933,7 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i40 [[CRC_LE_LSHR]] to i32
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
-; PCLMUL-NEXT:    br i1 true, label %[[EXIT:.*]], label %[[LOOP]]
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
 ; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]

>From fee3ad50d3d5714b475567297b8da7473731cd38 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Fri, 26 Jun 2026 23:09:57 -0500
Subject: [PATCH 15/18] Minor comment changes

---
 llvm/lib/Analysis/HashRecognize.cpp               | 4 ++--
 llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index e17c03ad35a84..3884d260a4aac 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -388,7 +388,7 @@ static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
   // Extend the divisor bit width to match the dividend.
   Divisor = Divisor.zext(Dividend.getBitWidth());
 
-  // Note that getActiveBits(x) returns deg(x)+1, but the computation below
+  // Note that getActiveBits(_) returns deg(_)+1, but the computation below
   // still holds.
   unsigned DivisorActiveBits = Divisor.getActiveBits();
 
@@ -439,7 +439,7 @@ HashRecognize::genBarrettConstants(const APInt &GenPoly, unsigned TripCount,
     FullGenPoly = FullGenPoly.reverseBits();
   }
 
-  // The final constants are mu/mu' and P(x)/P(x)', depending on
+  // The final constants are (mu or mu') and (P(x) or P(x)'), depending on
   // IsBigEndian.
   return {Mu, FullGenPoly};
 }
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index a63d9bb9907e1..b4767009b024c 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1632,16 +1632,16 @@ bool LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info) {
     }
   }
 
-  // Perform the first clmul operation with the mu/mu' constant. Input is TC
-  // bits and Mu is TC+1 bits, so the result will be 2*TC bits.
+  // Perform the first clmul operation with the mu constant. Input is TC bits
+  // and mu is TC+1 bits, so the result will be 2*TC bits.
   Value *ClmulMu = Builder.CreateBinaryIntrinsic(
       Intrinsic::clmul, ClmulMuInput, MuExt, /*FMFSource=*/{}, "clmul.mu");
 
   // Extract the relevant bits from the result.
   Value *ClmulGPInput = GetMostSignificantTCBits(ClmulMu, 2 * TC, "quot");
 
-  // Perform the second clmul operation with the P(x)/P(x)' constant. Input is
-  // TC bits and GP is CRCBW+1 bits, so the result will be CRCBW+TC bits.
+  // Perform the second clmul operation with the P(x) constant. Input is TC bits
+  // and P(x) is CRCBW+1 bits, so the result will be CRCBW+TC bits.
   Value *ClmulGP = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulGPInput,
                                                  FullGenPolyExt,
                                                  /*FMFSource=*/{}, "clmul.gp");

>From 653bafed0a103ed29a2ae37f61175639d15047ab Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Mon, 29 Jun 2026 12:04:33 -0500
Subject: [PATCH 16/18] Apply suggested changes, fix crash, use
 getLargestLegalIntType

---
 llvm/include/llvm/Analysis/HashRecognize.h    |  12 +-
 llvm/include/llvm/CodeGen/BasicTTIImpl.h      |   5 +-
 llvm/lib/Analysis/HashRecognize.cpp           |   5 +-
 .../Transforms/Scalar/LoopIdiomRecognize.cpp  |  32 +-
 .../HashRecognize/cyclic-redundancy-check.ll  |  50 +
 .../AArch64/cyclic-redundancy-check.ll        | 126 ++-
 .../RISCV/cyclic-redundancy-check.ll          | 921 +++++++-----------
 .../LoopIdiom/X86/cyclic-redundancy-check.ll  | 126 ++-
 .../LoopIdiom/cyclic-redundancy-check.ll      |  48 +
 9 files changed, 677 insertions(+), 648 deletions(-)

diff --git a/llvm/include/llvm/Analysis/HashRecognize.h b/llvm/include/llvm/Analysis/HashRecognize.h
index 221e8f871b9fc..912ba2be1980e 100644
--- a/llvm/include/llvm/Analysis/HashRecognize.h
+++ b/llvm/include/llvm/Analysis/HashRecognize.h
@@ -90,13 +90,11 @@ class HashRecognize {
 
   // Auxilary entry point after analysis to generate constants for a GF(2)
   // Barrett Reduction.
-  // The first APInt is the constant used in the first clmul operation, which is
-  // mu = floor(x^(BW+TC) / P(x)); bit width is TC+1.
-  // The second APInt is the constant used in the second clmul operation, which
-  // is the generating polynomial P(x) with the implied x^BW term included; bit
-  // width is BW+1.
-  // Both constants are bit-reflected across their respective
-  // widths for bit-reflected CRCs.
+  // Returns a pair of Mu of bitwidth TC+1 and FullGenPoly of bitwidth BW+1.
+  // Mu is used in the first clmul operation. Mu = floor(x^(BW+TC) / P(x)).
+  // FullGenPoly is used in the second clmul operation, and is \p GenPoly
+  // with the implied BW'th bit.
+  // Endianness is accounted for using \p ByteOrderSwapped.
   LLVM_ABI static std::pair<APInt, APInt>
   genBarrettConstants(const APInt &GenPoly, unsigned TripCount,
                       bool ByteOrderSwapped);
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 36e62ddc4c237..9663d59b0d9c8 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -679,8 +679,9 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
   bool haveFastClmul(IntegerType *Ty) const override {
     // FIXME: clmul should really be Promote for any bitwidth under the largest
     // legal bitwidth for clmul. This is a hack to get around that shortcoming.
-    if (auto *PromoteTy = dyn_cast_if_present<IntegerType>(
-            DL.getSmallestLegalIntType(Ty->getContext(), Ty->getBitWidth())))
+    auto *PromoteTy = dyn_cast_if_present<IntegerType>(
+        DL.getLargestLegalIntType(Ty->getContext()));
+    if (PromoteTy && Ty->getBitWidth() <= PromoteTy->getBitWidth())
       Ty = PromoteTy;
 
     const TargetLoweringBase *TLI = getTLI();
diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index 3884d260a4aac..cb7baa0427654 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -395,7 +395,8 @@ static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
   // Q = 0
   APInt Quotient = APInt::getZero(Dividend.getBitWidth());
   // S != 0 and deg(S) >= deg(P)
-  while (!Dividend.isZero() && Dividend.getActiveBits() >= DivisorActiveBits) {
+  // (S != 0 implied by DivisorActiveBits > 0)
+  while (Dividend.getActiveBits() >= DivisorActiveBits) {
     // T = S[deg(S)] / P[deg(P)]
     unsigned Shift = Dividend.getActiveBits() - DivisorActiveBits;
     // Q = Q + T
@@ -640,7 +641,7 @@ void HashRecognize::print(raw_ostream &OS) const {
   Mu.print(OS, false);
   OS << ", FullGenPoly = ";
   FullGenPoly.print(OS, false);
-  OS << '\n';
+  OS << "\n";
 }
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index b4767009b024c..c0369fec3eeaa 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1581,10 +1581,11 @@ bool LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info) {
 
   IRBuilder<> Builder(CurLoop->getLoopPreheader()->getTerminator());
 
-  auto GetMostSignificantTCBits = [&, TC](Value *Op, unsigned BW,
-                                          const Twine &Name) {
+  auto GetMostSignificantTCBits = [&](Value *Op, unsigned BW,
+                                      const Twine &Name) {
     unsigned OpBW = Op->getType()->getIntegerBitWidth();
-    assert(BW > TC && OpBW > TC);
+    assert(BW > TC && OpBW > TC &&
+           "Trip count should not exceed the bit width");
     if (Info.IsBigEndian)
       return Builder.CreateLShr(Op, BW - TC, Name + ".be.lshr");
     auto *Mask = ConstantInt::get(Ctx, APInt::getLowBitsSet(OpBW, TC));
@@ -1600,12 +1601,12 @@ bool LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info) {
   if (!Info.IsBigEndian || CRCBW == TC)
     CRCAlignTC = LHS;
   else if (CRCBW > TC)
-    CRCAlignTC = Builder.CreateLShr(LHS, CRCBW - TC, "crc.be.lshr");
+    CRCAlignTC = Builder.CreateLShr(LHS, CRCBW - TC, "crc.be.tcbits");
   else
-    CRCAlignTC = Builder.CreateShl(LHS, TC - CRCBW, "crc.be.shl");
+    CRCAlignTC = Builder.CreateShl(LHS, TC - CRCBW, "crc.be.tcbits");
 
   // If auxiliary data is present, XOR it in with the CRC.
-  Value *ClmulMuInput = CRCAlignTC;
+  Value *ClmulMuInput;
   if (Value *Data = Info.LHSAux) {
     unsigned DataBW = Data->getType()->getIntegerBitWidth();
     // For big-endian CRC loops where auxiliary data is XORed with the CRC
@@ -1625,11 +1626,16 @@ bool LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info) {
         // Extract the useful bits of the data and discard the rest.
         Data = GetMostSignificantTCBits(Data, DataBW, "data");
       }
-      // This is always a zext since TripCount <= DataBW < ClmulBW.
-      Data = Builder.CreateZExt(Data, ClmulTy, "data.ext");
+      // This is usually a zext, but DataBW may exceed ClmulBW if both CRCBW and
+      // TC are small enough.
+      Data = Builder.CreateZExtOrTrunc(Data, ClmulTy, "data.cast");
 
       ClmulMuInput = Builder.CreateXor(CRCAlignTC, Data, "xor.crc.data");
+    } else {
+      ClmulMuInput = CRCAlignTC;
     }
+  } else {
+    ClmulMuInput = CRCAlignTC;
   }
 
   // Perform the first clmul operation with the mu constant. Input is TC bits
@@ -1674,16 +1680,14 @@ bool LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info) {
       PN.replaceAllUsesWith(PoisonValue::get(PN.getType()));
       LoopPHIs.push_back(&PN);
     }
-    for (PHINode *PN : LoopPHIs) {
+    for (PHINode *PN : LoopPHIs)
       RecursivelyDeleteDeadPHINode(PN);
-    }
     // Replace the exit condition with constant true/false to always cause a
     // branch to the exit block.
     deleteDeadInstruction(CurLoop->getLatchCmpInst());
-    CondBrInst *BrInst =
-        cast<CondBrInst>(CurLoop->getLoopLatch()->getTerminator());
-    bool BrToExitCond = BrInst->getSuccessor(0) == CurLoop->getExitBlock();
-    BrInst->setCondition(ConstantInt::getBool(Ctx, BrToExitCond));
+    auto *BrInst = cast<CondBrInst>(CurLoop->getLoopLatch()->getTerminator());
+    BrInst->setCondition(ConstantInt::getBool(
+        Ctx, BrInst->getSuccessor(0) == CurLoop->getExitBlock()));
     SE->forgetLoop(CurLoop);
   }
 
diff --git a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
index c51ecfea886b8..3e31116285e6f 100644
--- a/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
+++ b/llvm/test/Analysis/HashRecognize/cyclic-redundancy-check.ll
@@ -640,6 +640,56 @@ exit:                                              ; preds = %loop
   ret i32 %crc.next
 }
 
+define i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) {
+; CHECK-LABEL: 'crc8.le.tc8.data32'
+; CHECK-NEXT:  Found little-endian CRC-8 loop with trip count 8
+; CHECK-NEXT:    Initial CRC: i8 %checksum
+; CHECK-NEXT:    Generating polynomial: 59
+; CHECK-NEXT:    Computed CRC: %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+; CHECK-NEXT:    Auxiliary data: i32 %msg
+; CHECK-NEXT:    Computed CRC lookup table:
+; CHECK-NEXT:  0 16 32 48 55 39 23 7 25 9 57 41 46 62 14 30
+; CHECK-NEXT:  50 34 18 2 5 21 37 53 43 59 11 27 28 12 60 44
+; CHECK-NEXT:  19 3 51 35 36 52 4 20 10 26 42 58 61 45 29 13
+; CHECK-NEXT:  33 49 1 17 22 6 54 38 56 40 24 8 15 31 47 63
+; CHECK-NEXT:  38 54 6 22 17 1 49 33 63 47 31 15 8 24 40 56
+; CHECK-NEXT:  20 4 52 36 35 51 3 19 13 29 45 61 58 42 26 10
+; CHECK-NEXT:  53 37 21 5 2 18 34 50 44 60 12 28 27 11 59 43
+; CHECK-NEXT:  7 23 39 55 48 32 16 0 30 14 62 46 41 57 9 25
+; CHECK-NEXT:  59 43 27 11 12 28 44 60 34 50 2 18 21 5 53 37
+; CHECK-NEXT:  9 25 41 57 62 46 30 14 16 0 48 32 39 55 7 23
+; CHECK-NEXT:  40 56 8 24 31 15 63 47 49 33 17 1 6 22 38 54
+; CHECK-NEXT:  26 10 58 42 45 61 13 29 3 19 35 51 52 36 20 4
+; CHECK-NEXT:  29 13 61 45 42 58 10 26 4 20 36 52 51 35 19 3
+; CHECK-NEXT:  47 63 15 31 24 8 56 40 54 38 22 6 1 17 33 49
+; CHECK-NEXT:  14 30 46 62 57 41 25 9 23 7 55 39 32 48 0 16
+; CHECK-NEXT:  60 44 28 12 11 27 43 59 37 53 5 21 18 2 50 34
+; CHECK-NEXT:    Computed CRC Barrett constants:
+; CHECK-NEXT:  Mu = 107, FullGenPoly = 119
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %data.trunc = trunc i32 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %sb.crc.data = and i8 %xor.crc.data, 1
+  %check.sb = icmp eq i8 %sb.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 59
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i16 @crc16.be.tc8.zext.data(i8 %msg, i16 %checksum) {
 ; CHECK-LABEL: 'crc16.be.tc8.zext.data'
 ; CHECK-NEXT:  Found big-endian CRC-16 loop with trip count 8
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
index 85696cbad83aa..6a91a0508b3a4 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/cyclic-redundancy-check.ll
@@ -16,6 +16,7 @@
 ; NOAES: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOAES: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOAES: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOAES: @.crctable.13 = private constant [256 x i8] c"\00\10 07'\17\07\19\099).>\0E\1E2\22\12\02\05\15%5+
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOAES-LABEL: define i16 @crc16.le.tc8(
@@ -45,8 +46,8 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
@@ -111,8 +112,8 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
-; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
+; AES-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
@@ -178,8 +179,8 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; AES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 114687)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
@@ -243,8 +244,8 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 24423)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 59)
@@ -313,8 +314,8 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; AES-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; AES-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -374,8 +375,8 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -432,8 +433,8 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; AES-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -594,8 +595,8 @@ define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
 ; AES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 69936)
 ; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
@@ -659,8 +660,8 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
 ; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; AES-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; AES-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -723,21 +724,21 @@ define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
 ; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
-; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; AES-NEXT:    [[CRC_BE_TCBITS:%.*]] = shl i32 [[CRC_EXT]], 8
 ; AES-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_SHL]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_TCBITS]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 72779)
 ; AES-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 285)
-; AES-NEXT:    [[CRC_BE_SHL2:%.*]] = shl i32 [[CRC_EXT]], 16
-; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL2]], [[CLMUL_GP]]
-; AES-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
+; AES-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
 ; AES-NEXT:    br label %[[LOOP:.*]]
 ; AES:       [[LOOP]]:
 ; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; AES:       [[EXIT]]:
-; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -858,8 +859,8 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
@@ -895,6 +896,73 @@ exit:                                              ; preds = %loop
   ret i32 %crc.next
 }
 
+define i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) {
+; NOAES-LABEL: define i8 @crc8.le.tc8.data32(
+; NOAES-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOAES-NEXT:  [[ENTRY:.*]]:
+; NOAES-NEXT:    br label %[[LOOP:.*]]
+; NOAES:       [[LOOP]]:
+; NOAES-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOAES-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOAES-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOAES-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOAES-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i32
+; NOAES-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOAES-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOAES-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOAES-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.13, i64 [[INDEXER_EXT]]
+; NOAES-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOAES-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOAES-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOAES-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOAES:       [[EXIT]]:
+; NOAES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOAES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; AES-LABEL: define i8 @crc8.le.tc8.data32(
+; AES-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; AES-NEXT:  [[ENTRY:.*:]]
+; AES-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
+; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; AES-NEXT:    [[DATA_CAST:%.*]] = trunc i32 [[DATA_LE_MASK]] to i16
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_CAST]]
+; AES-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 107)
+; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i16 [[CLMUL_MU]], 255
+; AES-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LE_MASK]], i16 119)
+; AES-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_EXT]], [[CLMUL_GP]]
+; AES-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i16 [[XOR_CRC_MULT]], 8
+; AES-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[CRC_LE_LSHR]] to i8
+; AES-NEXT:    br label %[[LOOP:.*]]
+; AES:       [[LOOP]]:
+; AES-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; AES:       [[EXIT]]:
+; AES-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; AES-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %data.trunc = trunc i32 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %sb.crc.data = and i8 %xor.crc.data, 1
+  %check.sb = icmp eq i8 %sb.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 59
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; NOAES-LABEL: define i32 @crc.disabled.optsize(
 ; NOAES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
@@ -923,8 +991,8 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; AES-NEXT:  [[ENTRY:.*:]]
 ; AES-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; AES-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; AES-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
-; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; AES-NEXT:    [[DATA_CAST:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; AES-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_CAST]]
 ; AES-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
 ; AES-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
 ; AES-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
diff --git a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
index 03ee5660c2c13..6ad22d2e7a676 100644
--- a/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
 ; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,NOZBC,NOZBC32 %s
-; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ZBC,ZBC32 %s
 ; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,NOZBC,NOZBC64 %s
+; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ZBC,ZBC32 %s
 ; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ZBC,ZBC64 %s
 
 ;.
@@ -18,8 +18,7 @@
 ; NOZBC32: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOZBC32: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOZBC32: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
-;.
-; ZBC32: @.crctable = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOZBC32: @.crctable.13 = private constant [256 x i8] c"\00\10 07'\17\07\19\099).>\0E\1E2\22\12\02\05\15%5+
 ;.
 ; NOZBC64: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
 ; NOZBC64: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
@@ -34,19 +33,9 @@
 ; NOZBC64: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOZBC64: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOZBC64: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOZBC64: @.crctable.13 = private constant [256 x i8] c"\00\10 07'\17\07\19\099).>\0E\1E2\22\12\02\05\15%5+
 ;.
-; ZBC64: @.crctable = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
-; ZBC64: @.crctable.1 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
-; ZBC64: @.crctable.2 = private constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
-; ZBC64: @.crctable.3 = private constant [256 x i8] c"\00\09\12\1B\1F\16\0D\04\05\0C\17\1E\1A\13\08\01\0A\03\18\11\15\1C\07\0E\0F\06\1D\14\10\19\02\0B\14\1D\06\0F\0B\02\19\10\11\18\03\0A\0E\07\1C\15\1E\17\0C\05\01\08\13\1A\1B\12\09\00\04\0D\16\1F\13\1A\01\08\0C\05\1E\17\16\1F\04\0D\09\00\1B\12\19\10\0B\02\06\0F\14\1D\1C\15\0E\07\03\0A\11\18\07\0E\15\1C\18\11\0A\03\02\0B\10\19\1D\14\0F\06\0D\04\1F\16\12\1B\00\09\08\01\1A\13\17\1E\05\0C\1D\14\0F\06\02\0B\10\19\18\11\0A\03\07\0E\15\1C\17\1E\05\0C\08\01\1A\13\12\1B\00\09\0D\04\1F\16\09\00\1B\12\16\1F\04\0D\0C\05\1E\17\13\1A\01\08\03\0A\11\18\1C\15\0E\07\06\0F\14\1D\19\10\0B\02\0E\07\1C\15\11\18\03\0A\0B\02\19\10\14\1D\06\0F\04\0D\16\1F\1B\12\09\00\01\08\13\1A\1E\17\0C\05\1A\13\08\01\05\0C\17\1E\1F\16\0D\04\00\09\12\1B\10\19\02\0B\0F\06\1D\14\15\1C\07\0E\0A\03\18\11"
-; ZBC64: @.crctable.4 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
-; ZBC64: @.crctable.5 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
-; ZBC64: @.crctable.6 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
-; ZBC64: @.crctable.7 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; ZBC64: @.crctable.8 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
-; ZBC64: @.crctable.9 = private constant [256 x i16] [i16 0, i16 4129, i16 8258, i16 12387, i16 16516, i16 20645, i16 24774, i16 28903, i16 -32504, i16 -28375, i16 -24246, i16 -20117, i16 -15988, i16 -11859, i16 -7730, i16 -3601, i16 4657, i16 528, i16 12915, i16 8786, i16 21173, i16 17044, i16 29431, i16 25302, i16 -27847, i16 -31976, i16 -19589, i16 -23718, i16 -11331, i16 -15460, i16 -3073, i16 -7202, i16 9314, i16 13379, i16 1056, i16 5121, i16 25830, i16 29895, i16 17572, i16 21637, i16 -23190, i16 -19125, i16 -31448, i16 -27383, i16 -6674, i16 -2609, i16 -14932, i16 -10867, i16 13907, i16 9842, i16 5649, i16 1584, i16 30423, i16 26358, i16 22165, i16 18100, i16 -18597, i16 -22662, i16 -26855, i16 -30920, i16 -2081, i16 -6146, i16 -10339, i16 -14404, i16 18628, i16 22757, i16 26758, i16 30887, i16 2112, i16 6241, i16 10242, i16 14371, i16 -13876, i16 -9747, i16 -5746, i16 -1617, i16 -30392, i16 -26263, i16 -22262, i16 -18133, i16 23285, i16 19156, i16 31415, i16 27286, i16 6769, i16 2640, i16 14899, i16 10770, i16 -9219, i16 -13348, i16 -1089, i16 -5218, i16 -25735, i16 -29864, i16 -17605, i16 -21734, i16 27814, i16 31879, i16 19684, i16 23749, i16 11298, i16 15363, i16 3168, i16 7233, i16 -4690, i16 -625, i16 -12820, i16 -8755, i16 -21206, i16 -17141, i16 -29336, i16 -25271, i16 32407, i16 28342, i16 24277, i16 20212, i16 15891, i16 11826, i16 7761, i16 3696, i16 -97, i16 -4162, i16 -8227, i16 -12292, i16 -16613, i16 -20678, i16 -24743, i16 -28808, i16 -28280, i16 -32343, i16 -20022, i16 -24085, i16 -12020, i16 -16083, i16 -3762, i16 -7825, i16 4224, i16 161, i16 12482, i16 8419, i16 20484, i16 16421, i16 28742, i16 24679, i16 -31815, i16 -27752, i16 -23557, i16 -19494, i16 -15555, i16 -11492, i16 -7297, i16 -3234, i16 689, i16 4752, i16 8947, i16 13010, i16 16949, i16 21012, i16 25207, i16 29270, i16 -18966, i16 -23093, i16 -27224, i16 -31351, i16 -2706, i16 -6833, i16 -10964, i16 -15091, i16 13538, i16 9411, i16 5280, i16 1153, i16 29798, i16 25671, i16 21540, i16 17413, i16 -22565, i16 -18438, i16 -30823, i16 -26696, i16 -6305, i16 -2178, i16 -14563, i16 -10436, i16 9939, i16 14066, i16 1681, i16 5808, i16 26199, i16 30326, i16 17941, i16 22068, i16 -9908, i16 -13971, i16 -1778, i16 -5841, i16 -26168, i16 -30231, i16 -18038, i16 -22101, i16 22596, i16 18533, i16 30726, i16 26663, i16 6336, i16 2273, i16 14466, i16 10403, i16 -13443, i16 -9380, i16 -5313, i16 -1250, i16 -29703, i16 -25640, i16 -21573, i16 -17510, i16 19061, i16 23124, i16 27191, i16 31254, i16 2801, i16 6864, i16 10931, i16 14994, i16 -722, i16 -4849, i16 -8852, i16 -12979, i16 -16982, i16 -21109, i16 -25112, i16 -29239, i16 31782, i16 27655, i16 23652, i16 19525, i16 15522, i16 11395, i16 7392, i16 3265, i16 -4321, i16 -194, i16 -12451, i16 -8324, i16 -20581, i16 -16454, i16 -28711, i16 -24584, i16 28183, i16 32310, i16 20053, i16 24180, i16 11923, i16 16050, i16 3793, i16 7920]
-; ZBC64: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
-; ZBC64: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
+; ZBC32: @.crctable = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOZBC32-LABEL: define i16 @crc16.le.tc8(
@@ -72,25 +61,6 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.le.tc8(
-; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
-; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc8(
 ; NOZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -114,28 +84,24 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.le.tc8(
-; ZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.le.tc8(
+; ZBC-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; ZBC-NEXT:    [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
+; ZBC-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_CAST]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; ZBC-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; ZBC-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -184,25 +150,6 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.le.tc8.udiv(
-; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
-; ZBC32-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc8.udiv(
 ; NOZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -226,28 +173,24 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.le.tc8.udiv(
-; ZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i8 [[MSG]], [[IV_BITS]]
-; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC_DATA_INDEXER]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.1, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.le.tc8.udiv(
+; ZBC-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; ZBC-NEXT:    [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
+; ZBC-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_CAST]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
+; ZBC-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
+; ZBC-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[CRC_LE_LSHR]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -297,25 +240,6 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.le.tc16(
-; ZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 114687)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
-; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.le.tc16(
 ; NOZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -340,29 +264,24 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.le.tc16(
-; ZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
-; ZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.2, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_LE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.le.tc16(
+; ZBC-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; ZBC-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; ZBC-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 114687)
+; ZBC-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; ZBC-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -410,25 +329,6 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i8 @crc8.le.tc16(
-; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 24423)
-; ZBC32-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 59)
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
-; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i8 @crc8.le.tc16(
 ; NOZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -452,28 +352,24 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i8 @crc8.le.tc16(
-; ZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i16 [[MSG]], [[IV_INDEXER]]
-; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.3, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i8 @crc8.le.tc16(
+; ZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; ZBC-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; ZBC-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 24423)
+; ZBC-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 59)
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
+; ZBC-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[CRC_LE_LSHR]] to i8
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -523,27 +419,6 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.li(
-; ZBC32-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
-; ZBC32-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
-; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
 ; NOZBC64-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -568,29 +443,26 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.li(
-; ZBC64-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
-; ZBC64-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
-; ZBC64-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.4, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.be.tc8.crc.init.li(
+; ZBC-SAME: i16 [[CHECKSUM:%.*]], i8 [[MSG:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[MSG_EXT:%.*]] = zext i8 [[MSG]] to i16
+; ZBC-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
+; ZBC-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; ZBC-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   %msg.ext = zext i8 %msg to i16
@@ -635,24 +507,6 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
-; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
 ; NOZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -674,26 +528,23 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
-; ZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.5, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.be.tc8.crc.init.arg(
+; ZBC-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; ZBC-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -735,24 +586,6 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
-; ZBC32-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
 ; NOZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -774,26 +607,23 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
-; ZBC64-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CRC_INIT]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.6, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(
+; ZBC-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
+; ZBC-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -846,38 +676,6 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; NOZBC32-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
 ; NOZBC32-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
 ;
-; ZBC32-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
-; ZBC32-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
-; ZBC32-NEXT:    br label %[[OUTER_LOOP:.*]]
-; ZBC32:       [[OUTER_LOOP]]:
-; ZBC32-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
-; ZBC32-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
-; ZBC32-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
-; ZBC32-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
-; ZBC32:       [[PH]]:
-; ZBC32-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
-; ZBC32-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
-; ZBC32-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
-; ZBC32-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CRC_INIT]] to i16
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_EXT]], i16 284)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
-; ZBC32-NEXT:    br label %[[INNER_LOOP:.*]]
-; ZBC32:       [[INNER_LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[INNER_LOOP]], label %[[INNER_EXIT]]
-; ZBC32:       [[INNER_EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
-; ZBC32-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
-; ZBC32-NEXT:    br label %[[OUTER_LOOP]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
-; ZBC32-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
-;
 ; NOZBC64-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
 ; NOZBC64-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -910,37 +708,37 @@ define i8 @crc8.be.tc8.ptr.nested.loop(ptr %msg, i32 %loop.limit) {
 ; NOZBC64-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
 ; NOZBC64-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
 ;
-; ZBC64-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
-; ZBC64-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[OUTER_LOOP:.*]]
-; ZBC64:       [[OUTER_LOOP]]:
-; ZBC64-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
-; ZBC64-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
-; ZBC64-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
-; ZBC64-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
-; ZBC64:       [[PH]]:
-; ZBC64-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
-; ZBC64-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
-; ZBC64-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
-; ZBC64-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
-; ZBC64-NEXT:    br label %[[INNER_LOOP:.*]]
-; ZBC64:       [[INNER_LOOP]]:
-; ZBC64-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 0, %[[PH]] ], [ [[INNER_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CRC_INIT]], %[[PH]] ], [ [[TBL_LD:%.*]], %[[INNER_LOOP]] ]
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[CRC2]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.7, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; ZBC64-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i32 [[INNER_IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[INNER_LOOP]], label %[[INNER_EXIT]]
-; ZBC64:       [[INNER_EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[TBL_LD]], %[[INNER_LOOP]] ]
-; ZBC64-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
-; ZBC64-NEXT:    br label %[[OUTER_LOOP]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
-; ZBC64-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
+; ZBC-LABEL: define i8 @crc8.be.tc8.ptr.nested.loop(
+; ZBC-SAME: ptr [[MSG:%.*]], i32 [[LOOP_LIMIT:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*]]:
+; ZBC-NEXT:    br label %[[OUTER_LOOP:.*]]
+; ZBC:       [[OUTER_LOOP]]:
+; ZBC-NEXT:    [[CRC_OUTER:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[CRC_NEXT_LCSSA:%.*]], %[[INNER_EXIT:.*]] ]
+; ZBC-NEXT:    [[OUTER_IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[INNER_EXIT]] ]
+; ZBC-NEXT:    [[OUTER_EXIT_COND:%.*]] = icmp ult i32 [[OUTER_IV]], [[LOOP_LIMIT]]
+; ZBC-NEXT:    br i1 [[OUTER_EXIT_COND]], label %[[PH:.*]], label %[[EXIT:.*]]
+; ZBC:       [[PH]]:
+; ZBC-NEXT:    [[OUTER_IV_EXT:%.*]] = sext i32 [[OUTER_IV]] to i64
+; ZBC-NEXT:    [[MSG_OUTER_IV:%.*]] = getelementptr inbounds i8, ptr [[MSG]], i64 [[OUTER_IV_EXT]]
+; ZBC-NEXT:    [[MSG_LOAD:%.*]] = load i8, ptr [[MSG_OUTER_IV]], align 1
+; ZBC-NEXT:    [[CRC_INIT:%.*]] = xor i8 [[MSG_LOAD]], [[CRC_OUTER]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CRC_INIT]] to i16
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_EXT]], i16 284)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT1:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
+; ZBC-NEXT:    br label %[[INNER_LOOP:.*]]
+; ZBC:       [[INNER_LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[INNER_LOOP]], label %[[INNER_EXIT]]
+; ZBC:       [[INNER_EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA]] = phi i8 [ [[CRC_NEXT1]], %[[INNER_LOOP]] ]
+; ZBC-NEXT:    [[OUTER_IV_NEXT]] = add i32 [[OUTER_IV]], 1
+; ZBC-NEXT:    br label %[[OUTER_LOOP]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_OUTER_LCSSA:%.*]] = phi i8 [ [[CRC_OUTER]], %[[OUTER_LOOP]] ]
+; ZBC-NEXT:    ret i8 [[CRC_OUTER_LCSSA]]
 ;
 entry:
   br label %outer.loop
@@ -1003,25 +801,6 @@ define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.be.tc16(
-; ZBC32-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 69936)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc16(
 ; NOZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -1047,30 +826,24 @@ define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.be.tc16(
-; ZBC64-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC2]]
-; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i16 [[CRC_DATA_INDEXER]], 8
-; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[INDEXER_HI]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.8, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.be.tc16(
+; ZBC-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
+; ZBC-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; ZBC-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 69936)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -1118,24 +891,6 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i16 @crc16.be.tc8.misalign(
-; ZBC32-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; ZBC32-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i16 @crc16.be.tc8.misalign(
 ; NOZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -1160,29 +915,23 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i16 @crc16.be.tc8.misalign(
-; ZBC64-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i8 [[MSG]], [[IV_BITS]]
-; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = trunc i16 [[CRC2]] to i8
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i8 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC64-NEXT:    [[INDEXER_HI:%.*]] = lshr i8 [[CRC_DATA_INDEXER]], 8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i16, ptr @.crctable.9, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD:%.*]] = load i16, ptr [[TBL_PTRADD]], align 2
-; ZBC64-NEXT:    [[CRC_BE_SHIFT:%.*]] = shl i16 [[CRC2]], 8
-; ZBC64-NEXT:    [[CRC_NEXT3]] = xor i16 [[CRC_BE_SHIFT]], [[TBL_LD]]
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i16 @crc16.be.tc8.misalign(
+; ZBC-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
+; ZBC-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT1:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT1]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i16 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -1230,27 +979,6 @@ define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i8 @crc8.be.tc16.misalign(
-; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
-; ZBC32-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
-; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_SHL]], [[DATA_EXT]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 72779)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 285)
-; ZBC32-NEXT:    [[CRC_BE_SHL2:%.*]] = shl i32 [[CRC_EXT]], 16
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL2]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i8 @crc8.be.tc16.misalign(
 ; NOZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -1274,28 +1002,26 @@ define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i8 @crc8.be.tc16.misalign(
-; ZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
-; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.10, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 1
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i8 @crc8.be.tc16.misalign(
+; ZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
+; ZBC-NEXT:    [[CRC_BE_TCBITS:%.*]] = shl i32 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; ZBC-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
+; ZBC-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_TCBITS]], [[DATA_CAST]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 72779)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 285)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -1343,26 +1069,6 @@ define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i8 @crc8.be.tc8.data16.misalign(
-; ZBC32-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*:]]
-; ZBC32-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
-; ZBC32-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
-; ZBC32-NEXT:    [[DATA_BE_LSHR:%.*]] = lshr i16 [[DATA_BE_SHL]], 8
-; ZBC32-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_BE_LSHR]]
-; ZBC32-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 284)
-; ZBC32-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
-; ZBC32-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
-; ZBC32-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
-; ZBC32-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
-; ZBC32-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i8 @crc8.be.tc8.data16.misalign(
 ; NOZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -1386,28 +1092,25 @@ define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC64-LABEL: define i8 @crc8.be.tc8.data16.misalign(
-; ZBC64-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
-; ZBC64-NEXT:  [[ENTRY:.*]]:
-; ZBC64-NEXT:    br label %[[LOOP:.*]]
-; ZBC64:       [[LOOP]]:
-; ZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
-; ZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i16
-; ZBC64-NEXT:    [[DATA_INDEXER:%.*]] = shl i16 [[MSG]], [[IV_INDEXER]]
-; ZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i16
-; ZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i16 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
-; ZBC64-NEXT:    [[INDEXER_HI_LO_BYTE:%.*]] = trunc i16 [[CRC_DATA_INDEXER]] to i8
-; ZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_HI_LO_BYTE]] to i64
-; ZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.11, i64 [[INDEXER_EXT]]
-; ZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
-; ZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC64:       [[EXIT]]:
-; ZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
-; ZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+; ZBC-LABEL: define i8 @crc8.be.tc8.data16.misalign(
+; ZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
+; ZBC-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
+; ZBC-NEXT:    [[DATA_BE_LSHR:%.*]] = lshr i16 [[DATA_BE_SHL]], 8
+; ZBC-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_BE_LSHR]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 284)
+; ZBC-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_BE_LSHR]], i16 285)
+; ZBC-NEXT:    [[CRC_BE_SHL:%.*]] = shl i16 [[CRC_EXT]], 8
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
   br label %loop
@@ -1456,30 +1159,6 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
-; ZBC32-LABEL: define i32 @crc32.le.tc8.data32(
-; ZBC32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
-; ZBC32-NEXT:  [[ENTRY:.*]]:
-; ZBC32-NEXT:    br label %[[LOOP:.*]]
-; ZBC32:       [[LOOP]]:
-; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
-; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
-; ZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
-; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
-; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
-; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
-; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
-; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable, i32 [[INDEXER_EXT]]
-; ZBC32-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
-; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
-; ZBC32-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
-; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
-; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
-; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
-; ZBC32:       [[EXIT]]:
-; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
-; ZBC32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
-;
 ; NOZBC64-LABEL: define i32 @crc32.le.tc8.data32(
 ; NOZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; NOZBC64-NEXT:  [[ENTRY:.*]]:
@@ -1504,13 +1183,37 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
 ; NOZBC64-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
 ;
+; ZBC32-LABEL: define i32 @crc32.le.tc8.data32(
+; ZBC32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; ZBC32-NEXT:  [[ENTRY:.*]]:
+; ZBC32-NEXT:    br label %[[LOOP:.*]]
+; ZBC32:       [[LOOP]]:
+; ZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[CRC2:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT3:%.*]], %[[LOOP]] ]
+; ZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; ZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; ZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; ZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC2]]
+; ZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; ZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; ZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i32, ptr @.crctable, i32 [[INDEXER_EXT]]
+; ZBC32-NEXT:    [[TBL_LD:%.*]] = load i32, ptr [[TBL_PTRADD]], align 4
+; ZBC32-NEXT:    [[CRC_LE_SHIFT:%.*]] = lshr i32 [[CRC2]], 8
+; ZBC32-NEXT:    [[CRC_NEXT3]] = xor i32 [[CRC_LE_SHIFT]], [[TBL_LD]]
+; ZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; ZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC32:       [[EXIT]]:
+; ZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; ZBC32-NEXT:    ret i32 [[CRC_NEXT_LCSSA]]
+;
 ; ZBC64-LABEL: define i32 @crc32.le.tc8.data32(
 ; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
 ; ZBC64-NEXT:  [[ENTRY:.*:]]
 ; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
-; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC64-NEXT:    [[DATA_CAST:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_CAST]]
 ; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
 ; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
 ; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
@@ -1546,6 +1249,96 @@ exit:                                              ; preds = %loop
   ret i32 %crc.next
 }
 
+define i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) {
+; NOZBC32-LABEL: define i8 @crc8.le.tc8.data32(
+; NOZBC32-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOZBC32-NEXT:  [[ENTRY:.*]]:
+; NOZBC32-NEXT:    br label %[[LOOP:.*]]
+; NOZBC32:       [[LOOP]]:
+; NOZBC32-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC32-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC32-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOZBC32-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOZBC32-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i32
+; NOZBC32-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC32-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOZBC32-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i32
+; NOZBC32-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.13, i32 [[INDEXER_EXT]]
+; NOZBC32-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC32-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC32-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC32-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC32:       [[EXIT]]:
+; NOZBC32-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC32-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; NOZBC64-LABEL: define i8 @crc8.le.tc8.data32(
+; NOZBC64-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOZBC64-NEXT:  [[ENTRY:.*]]:
+; NOZBC64-NEXT:    br label %[[LOOP:.*]]
+; NOZBC64:       [[LOOP]]:
+; NOZBC64-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOZBC64-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOZBC64-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOZBC64-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOZBC64-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i32
+; NOZBC64-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOZBC64-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOZBC64-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOZBC64-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.13, i64 [[INDEXER_EXT]]
+; NOZBC64-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOZBC64-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOZBC64-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOZBC64-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOZBC64:       [[EXIT]]:
+; NOZBC64-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOZBC64-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; ZBC-LABEL: define i8 @crc8.le.tc8.data32(
+; ZBC-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; ZBC-NEXT:  [[ENTRY:.*:]]
+; ZBC-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
+; ZBC-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; ZBC-NEXT:    [[DATA_CAST:%.*]] = trunc i32 [[DATA_LE_MASK]] to i16
+; ZBC-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_CAST]]
+; ZBC-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 107)
+; ZBC-NEXT:    [[QUOT_LE_MASK:%.*]] = and i16 [[CLMUL_MU]], 255
+; ZBC-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LE_MASK]], i16 119)
+; ZBC-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_EXT]], [[CLMUL_GP]]
+; ZBC-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i16 [[XOR_CRC_MULT]], 8
+; ZBC-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[CRC_LE_LSHR]] to i8
+; ZBC-NEXT:    br label %[[LOOP:.*]]
+; ZBC:       [[LOOP]]:
+; ZBC-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; ZBC:       [[EXIT]]:
+; ZBC-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; ZBC-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %data.trunc = trunc i32 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %sb.crc.data = and i8 %xor.crc.data, 1
+  %check.sb = icmp eq i8 %sb.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 59
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; NOZBC-LABEL: define i32 @crc.disabled.optsize(
 ; NOZBC-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
@@ -1596,8 +1389,8 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; ZBC64-NEXT:  [[ENTRY:.*:]]
 ; ZBC64-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; ZBC64-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; ZBC64-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
-; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; ZBC64-NEXT:    [[DATA_CAST:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; ZBC64-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_CAST]]
 ; ZBC64-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
 ; ZBC64-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
 ; ZBC64-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
@@ -1734,16 +1527,14 @@ exit:
 ; NOZBC32: attributes #[[ATTR0]] = { "target-features"="-zbc" }
 ; NOZBC32: attributes #[[ATTR1]] = { optsize "target-features"="-zbc" }
 ;.
+; NOZBC64: attributes #[[ATTR0]] = { "target-features"="-zbc" }
+; NOZBC64: attributes #[[ATTR1]] = { optsize "target-features"="-zbc" }
+;.
 ; ZBC32: attributes #[[ATTR0]] = { "target-features"="+zbc" }
 ; ZBC32: attributes #[[ATTR1]] = { optsize "target-features"="+zbc" }
 ; ZBC32: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
-; NOZBC64: attributes #[[ATTR0]] = { "target-features"="-zbc" }
-; NOZBC64: attributes #[[ATTR1]] = { optsize "target-features"="-zbc" }
-;.
 ; ZBC64: attributes #[[ATTR0]] = { "target-features"="+zbc" }
 ; ZBC64: attributes #[[ATTR1]] = { optsize "target-features"="+zbc" }
 ; ZBC64: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; ZBC: {{.*}}
diff --git a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
index 1c84a2b71ee80..3435728ba59ba 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
@@ -16,6 +16,7 @@
 ; NOPCLMUL: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOPCLMUL: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; NOPCLMUL: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; NOPCLMUL: @.crctable.13 = private constant [256 x i8] c"\00\10 07'\17\07\19\099).>\0E\1E2\22\12\02\05\15%5+
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; NOPCLMUL-LABEL: define i16 @crc16.le.tc8(
@@ -45,8 +46,8 @@ define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
@@ -111,8 +112,8 @@ define i16 @crc16.le.tc8.udiv(i8 %msg, i16 %checksum) {
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i8 [[MSG]] to i24
-; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
+; PCLMUL-NEXT:    [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_EXT]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[XOR_CRC_DATA]], i24 511)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LE_MASK]], i24 81923)
@@ -178,8 +179,8 @@ define i16 @crc16.le.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 114687)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 81923)
@@ -243,8 +244,8 @@ define i8 @crc8.le.tc16(i16 %msg, i8 %checksum) {
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 24423)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LE_MASK]], i32 59)
@@ -313,8 +314,8 @@ define i16 @crc16.be.tc8.crc.init.li(i16 %checksum, i8 %msg) {
 ; PCLMUL-NEXT:    [[MSG_SHL:%.*]] = shl nuw i16 [[MSG_EXT]], 8
 ; PCLMUL-NEXT:    [[CRC_INIT:%.*]] = xor i16 [[MSG_SHL]], [[CHECKSUM]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -374,8 +375,8 @@ define i16 @crc16.be.tc8.crc.init.arg(i16 %crc.init) {
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -432,8 +433,8 @@ define i16 @crc16.be.tc8.crc.init.arg.flipped.sb.check(i16 %crc.init) {
 ; PCLMUL-SAME: i16 [[CRC_INIT:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CRC_INIT]] to i24
-; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -594,8 +595,8 @@ define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i32
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[MSG]] to i32
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_EXT]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 69936)
 ; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 69665)
@@ -659,8 +660,8 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
 ; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i16 [[CHECKSUM]] to i24
-; PCLMUL-NEXT:    [[CRC_BE_LSHR:%.*]] = lshr i24 [[CRC_EXT]], 8
-; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_LSHR]], i24 273)
+; PCLMUL-NEXT:    [[CRC_BE_TCBITS:%.*]] = lshr i24 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_BE_TCBITS]], i24 273)
 ; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_BE_LSHR]], i24 69665)
 ; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i24 [[CRC_EXT]], 8
@@ -723,21 +724,21 @@ define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
 ; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i32
-; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 8
+; PCLMUL-NEXT:    [[CRC_BE_TCBITS:%.*]] = shl i32 [[CRC_EXT]], 8
 ; PCLMUL-NEXT:    [[DATA_BE_SHL:%.*]] = shl i16 [[MSG]], 8
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_SHL]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i16 [[DATA_BE_SHL]] to i32
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_BE_TCBITS]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[XOR_CRC_DATA1]], i32 72779)
 ; PCLMUL-NEXT:    [[QUOT_BE_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_BE_LSHR]], i32 285)
-; PCLMUL-NEXT:    [[CRC_BE_SHL2:%.*]] = shl i32 [[CRC_EXT]], 16
-; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL2]], [[CLMUL_GP]]
-; PCLMUL-NEXT:    [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
+; PCLMUL-NEXT:    [[CRC_BE_SHL:%.*]] = shl i32 [[CRC_EXT]], 16
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_BE_SHL]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
 ; PCLMUL-NEXT:    br label %[[LOOP:.*]]
 ; PCLMUL:       [[LOOP]]:
 ; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
 ; PCLMUL:       [[EXIT]]:
-; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
 ; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
 ;
 entry:
@@ -858,8 +859,8 @@ define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
@@ -895,6 +896,73 @@ exit:                                              ; preds = %loop
   ret i32 %crc.next
 }
 
+define i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) {
+; NOPCLMUL-LABEL: define i8 @crc8.le.tc8.data32(
+; NOPCLMUL-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; NOPCLMUL-NEXT:  [[ENTRY:.*]]:
+; NOPCLMUL-NEXT:    br label %[[LOOP:.*]]
+; NOPCLMUL:       [[LOOP]]:
+; NOPCLMUL-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; NOPCLMUL-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; NOPCLMUL-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; NOPCLMUL-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i32
+; NOPCLMUL-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; NOPCLMUL-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; NOPCLMUL-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; NOPCLMUL-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.13, i64 [[INDEXER_EXT]]
+; NOPCLMUL-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; NOPCLMUL-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; NOPCLMUL-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; NOPCLMUL-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; NOPCLMUL:       [[EXIT]]:
+; NOPCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; NOPCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+; PCLMUL-LABEL: define i8 @crc8.le.tc8.data32(
+; PCLMUL-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
+; PCLMUL-NEXT:  [[ENTRY:.*:]]
+; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i8 [[CHECKSUM]] to i16
+; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = trunc i32 [[DATA_LE_MASK]] to i16
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_EXT]], [[DATA_CAST]]
+; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[XOR_CRC_DATA1]], i16 107)
+; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i16 [[CLMUL_MU]], 255
+; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LE_MASK]], i16 119)
+; PCLMUL-NEXT:    [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_EXT]], [[CLMUL_GP]]
+; PCLMUL-NEXT:    [[CRC_LE_LSHR:%.*]] = lshr i16 [[XOR_CRC_MULT]], 8
+; PCLMUL-NEXT:    [[CRC_NEXT2:%.*]] = trunc i16 [[CRC_LE_LSHR]] to i8
+; PCLMUL-NEXT:    br label %[[LOOP:.*]]
+; PCLMUL:       [[LOOP]]:
+; PCLMUL-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
+; PCLMUL:       [[EXIT]]:
+; PCLMUL-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT2]], %[[LOOP]] ]
+; PCLMUL-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %data.trunc = trunc i32 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %sb.crc.data = and i8 %xor.crc.data, 1
+  %check.sb = icmp eq i8 %sb.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 59
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; NOPCLMUL-LABEL: define i32 @crc.disabled.optsize(
 ; NOPCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
@@ -923,8 +991,8 @@ define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; PCLMUL-NEXT:  [[ENTRY:.*:]]
 ; PCLMUL-NEXT:    [[CRC_EXT:%.*]] = zext i32 [[CHECKSUM]] to i40
 ; PCLMUL-NEXT:    [[DATA_LE_MASK:%.*]] = and i32 [[MSG]], 255
-; PCLMUL-NEXT:    [[DATA_EXT:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
-; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_EXT]]
+; PCLMUL-NEXT:    [[DATA_CAST:%.*]] = zext i32 [[DATA_LE_MASK]] to i40
+; PCLMUL-NEXT:    [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_EXT]], [[DATA_CAST]]
 ; PCLMUL-NEXT:    [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[XOR_CRC_DATA1]], i40 273)
 ; PCLMUL-NEXT:    [[QUOT_LE_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
 ; PCLMUL-NEXT:    [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_LE_MASK]], i40 67601)
diff --git a/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll b/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll
index 2d40608a0440a..f994fc605554a 100644
--- a/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll
+++ b/llvm/test/Transforms/LoopIdiom/cyclic-redundancy-check.ll
@@ -15,6 +15,7 @@
 ; CHECK: @.crctable.10 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; CHECK: @.crctable.11 = private constant [256 x i8] c"\00\1D:'tiNS\E8\F5\D2\CF\9C\81\A6\BB\CD\D0\F7\EA\B9\A4\83\9E%8\1F\02QLkv\87\9A\BD\A0\F3\EE\C9\D4orUH\1B\06!<JWpm>#\04\19\A2\BF\98\85\D6\CB\EC\F1\13\0E)4gz]@\FB\E6\C1\DC\8F\92\B5\A8\DE\C3\E4\F9\AA\B7\90\8D6+\0C\11B_xe\94\89\AE\B3\E0\FD\DA\C7|aF[\08\152/YDc~-0\17\0A\B1\AC\8B\96\C5\D8\FF\E2&
 ; CHECK: @.crctable.12 = private constant [256 x i32] [i32 0, i32 4489, i32 8978, i32 12955, i32 17956, i32 22445, i32 25910, i32 29887, i32 35912, i32 40385, i32 44890, i32 48851, i32 51820, i32 56293, i32 59774, i32 63735, i32 4225, i32 264, i32 13203, i32 8730, i32 22181, i32 18220, i32 30135, i32 25662, i32 40137, i32 36160, i32 49115, i32 44626, i32 56045, i32 52068, i32 63999, i32 59510, i32 8450, i32 12427, i32 528, i32 5017, i32 26406, i32 30383, i32 17460, i32 21949, i32 44362, i32 48323, i32 36440, i32 40913, i32 60270, i32 64231, i32 51324, i32 55797, i32 12675, i32 8202, i32 4753, i32 792, i32 30631, i32 26158, i32 21685, i32 17724, i32 48587, i32 44098, i32 40665, i32 36688, i32 64495, i32 60006, i32 55549, i32 51572, i32 16900, i32 21389, i32 24854, i32 28831, i32 1056, i32 5545, i32 10034, i32 14011, i32 52812, i32 57285, i32 60766, i32 64727, i32 34920, i32 39393, i32 43898, i32 47859, i32 21125, i32 17164, i32 29079, i32 24606, i32 5281, i32 1320, i32 14259, i32 9786, i32 57037, i32 53060, i32 64991, i32 60502, i32 39145, i32 35168, i32 48123, i32 43634, i32 25350, i32 29327, i32 16404, i32 20893, i32 9506, i32 13483, i32 1584, i32 6073, i32 61262, i32 65223, i32 52316, i32 56789, i32 43370, i32 47331, i32 35448, i32 39921, i32 29575, i32 25102, i32 20629, i32 16668, i32 13731, i32 9258, i32 5809, i32 1848, i32 65487, i32 60998, i32 56541, i32 52564, i32 47595, i32 43106, i32 39673, i32 35696, i32 33800, i32 38273, i32 42778, i32 46739, i32 49708, i32 54181, i32 57662, i32 61623, i32 2112, i32 6601, i32 11090, i32 15067, i32 20068, i32 24557, i32 28022, i32 31999, i32 38025, i32 34048, i32 47003, i32 42514, i32 53933, i32 49956, i32 61887, i32 57398, i32 6337, i32 2376, i32 15315, i32 10842, i32 24293, i32 20332, i32 32247, i32 27774, i32 42250, i32 46211, i32 34328, i32 38801, i32 58158, i32 62119, i32 49212, i32 53685, i32 10562, i32 14539, i32 2640, i32 7129, i32 28518, i32 32495, i32 19572, i32 24061, i32 46475, i32 41986, i32 38553, i32 34576, i32 62383, i32 57894, i32 53437, i32 49460, i32 14787, i32 10314, i32 6865, i32 2904, i32 32743, i32 28270, i32 23797, i32 19836, i32 50700, i32 55173, i32 58654, i32 62615, i32 32808, i32 37281, i32 41786, i32 45747, i32 19012, i32 23501, i32 26966, i32 30943, i32 3168, i32 7657, i32 12146, i32 16123, i32 54925, i32 50948, i32 62879, i32 58390, i32 37033, i32 33056, i32 46011, i32 41522, i32 23237, i32 19276, i32 31191, i32 26718, i32 7393, i32 3432, i32 16371, i32 11898, i32 59150, i32 63111, i32 50204, i32 54677, i32 41258, i32 45219, i32 33336, i32 37809, i32 27462, i32 31439, i32 18516, i32 23005, i32 11618, i32 15595, i32 3696, i32 8185, i32 63375, i32 58886, i32 54429, i32 50452, i32 45483, i32 40994, i32 37561, i32 33584, i32 31687, i32 27214, i32 22741, i32 18780, i32 15843, i32 11370, i32 7921, i32 3960]
+; CHECK: @.crctable.13 = private constant [256 x i8] c"\00\10 07'\17\07\19\099).>\0E\1E2\22\12\02\05\15%5+
 ;.
 define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) {
 ; CHECK-LABEL: define i16 @crc16.le.tc8(
@@ -631,6 +632,53 @@ exit:                                              ; preds = %loop
   ret i32 %crc.next
 }
 
+define i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) {
+; CHECK-LABEL: define i8 @crc8.le.tc8.data32(
+; CHECK-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[CRC2:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[TBL_LD:%.*]], %[[LOOP]] ]
+; CHECK-NEXT:    [[IV_BITS:%.*]] = shl i8 [[IV]], 3
+; CHECK-NEXT:    [[IV_INDEXER:%.*]] = zext i8 [[IV_BITS]] to i32
+; CHECK-NEXT:    [[DATA_INDEXER:%.*]] = lshr i32 [[MSG]], [[IV_INDEXER]]
+; CHECK-NEXT:    [[CRC_INDEXER_CAST:%.*]] = zext i8 [[CRC2]] to i32
+; CHECK-NEXT:    [[CRC_DATA_INDEXER:%.*]] = xor i32 [[DATA_INDEXER]], [[CRC_INDEXER_CAST]]
+; CHECK-NEXT:    [[INDEXER_LO:%.*]] = trunc i32 [[CRC_DATA_INDEXER]] to i8
+; CHECK-NEXT:    [[INDEXER_EXT:%.*]] = zext i8 [[INDEXER_LO]] to i64
+; CHECK-NEXT:    [[TBL_PTRADD:%.*]] = getelementptr inbounds i8, ptr @.crctable.13, i64 [[INDEXER_EXT]]
+; CHECK-NEXT:    [[TBL_LD]] = load i8, ptr [[TBL_PTRADD]], align 1
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; CHECK-NEXT:    [[EXIT_COND1:%.*]] = icmp ne i8 [[IV]], 0
+; CHECK-NEXT:    br i1 [[EXIT_COND1]], label %[[LOOP]], label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[TBL_LD]], %[[LOOP]] ]
+; CHECK-NEXT:    ret i8 [[CRC_NEXT_LCSSA]]
+;
+entry:
+  br label %loop
+
+loop:                                              ; preds = %loop, %entry
+  %crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
+  %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+  %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+  %data.trunc = trunc i32 %data to i8
+  %xor.crc.data = xor i8 %crc, %data.trunc
+  %sb.crc.data = and i8 %xor.crc.data, 1
+  %check.sb = icmp eq i8 %sb.crc.data, 0
+  %crc.lshr = lshr i8 %crc, 1
+  %crc.xor = xor i8 %crc.lshr, 59
+  %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
+  %iv.next = add nuw nsw i8 %iv, 1
+  %data.next = lshr i32 %data, 1
+  %exit.cond = icmp samesign ult i8 %iv, 7
+  br i1 %exit.cond, label %loop, label %exit
+
+exit:                                              ; preds = %loop
+  ret i8 %crc.next
+}
+
 define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
 ; CHECK-LABEL: define i32 @crc.disabled.optsize(
 ; CHECK-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0:[0-9]+]] {

>From 6ec5d5895b57720360fd53f23d4138ead6373bc1 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Mon, 29 Jun 2026 12:10:03 -0500
Subject: [PATCH 17/18] Simplify cleanup of loop PHIs

---
 llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index c0369fec3eeaa..15d53bbbf5441 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -32,6 +32,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
@@ -1673,15 +1674,10 @@ bool LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info) {
   // Finally, clean up the loop as much as possible so it can be trivially
   // deleted.
   {
-    // Add the loop PHI nodes to a worklist since deleting a PHI invalidates the
-    // iterator.
-    SmallVector<PHINode *, 3> LoopPHIs;
-    for (PHINode &PN : CurLoop->getHeader()->phis()) {
+    for (PHINode &PN : make_early_inc_range(CurLoop->getHeader()->phis())) {
       PN.replaceAllUsesWith(PoisonValue::get(PN.getType()));
-      LoopPHIs.push_back(&PN);
+      RecursivelyDeleteDeadPHINode(&PN);
     }
-    for (PHINode *PN : LoopPHIs)
-      RecursivelyDeleteDeadPHINode(PN);
     // Replace the exit condition with constant true/false to always cause a
     // branch to the exit block.
     deleteDeadInstruction(CurLoop->getLatchCmpInst());

>From 1f57e93775773f41f68bdeb53433e39dcfdb11c3 Mon Sep 17 00:00:00 2001
From: Sean Clarke <sclarke at tenstorrent.com>
Date: Mon, 29 Jun 2026 12:52:40 -0500
Subject: [PATCH 18/18] Format with clang-format

---
 llvm/lib/Analysis/HashRecognize.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Analysis/HashRecognize.cpp b/llvm/lib/Analysis/HashRecognize.cpp
index cb7baa0427654..8eefdd067db97 100644
--- a/llvm/lib/Analysis/HashRecognize.cpp
+++ b/llvm/lib/Analysis/HashRecognize.cpp
@@ -412,9 +412,9 @@ static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
 // (https://web.archive.org/web/20131224125630/https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf),
 // with some adjustments to account for the fact that bit width and trip count
 // can vary.
-std::pair<APInt, APInt>
-HashRecognize::genBarrettConstants(const APInt &GenPoly, unsigned TripCount,
-                                   bool IsBigEndian) {
+std::pair<APInt, APInt> HashRecognize::genBarrettConstants(const APInt &GenPoly,
+                                                           unsigned TripCount,
+                                                           bool IsBigEndian) {
   unsigned BW = GenPoly.getBitWidth();
 
   // Recover the full generating polynomial in normal form by reflecting the LE



More information about the llvm-commits mailing list