[llvm] [LoopIdiomRecognize] Enable clmul optimization for CRC loops (PR #203405)
Sean Clarke via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 12:13:03 PDT 2026
https://github.com/xarkenz updated https://github.com/llvm/llvm-project/pull/203405
>From c2529139ba77c3fa91406290dc91deae30c5830b 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 1/3] 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 0f51227a6b010..b168278f4391b 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 {
@@ -87,6 +104,11 @@ class HashRecognize {
LLVM_ABI static CRCTable genSarwateTable(const APInt &GenPoly,
bool ByteOrderSwapped);
+ // 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 7d58473b81265..c7d8e46ac8433 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1181,6 +1181,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 89fd4a1e7628e..d25e0ae81fb19 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -568,6 +568,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 e4b6bf51c7a4e..6f7bc0b21e030 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -669,6 +669,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 8974ce5734b13..9754c2863521d 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
@@ -532,6 +574,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;
@@ -566,6 +616,8 @@ void HashRecognize::print(raw_ostream &OS) const {
}
OS.indent(2) << "Computed CRC lookup table:\n";
genSarwateTable(Info.RHS, Info.ByteOrderSwapped).print(OS);
+ OS.indent(2) << "Computed CRC Barrett constants:\n";
+ genBarrettConstants(Info.RHS, Info.ByteOrderSwapped).print(OS);
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 856950ccae595..b1604593febf8 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -739,6 +739,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 7a08d99a9e505..be703f2377ae5 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.ByteOrderSwapped),
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(
@@ -1665,24 +1753,18 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
Indexer = Info.ByteOrderSwapped ? 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.ByteOrderSwapped
? 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.
@@ -1697,7 +1779,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 762e6eb986ff8373ebceb1e4c34ed220b4063b19 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 2/3] 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 3b2300c0564ff6539c2bf2f77bbaad607d91a144 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 3/3] 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 9754c2863521d..dbce1f96ea87d 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 be703f2377ae5..f5bdafab958c0 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.ByteOrderSwapped),
- 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(
@@ -1753,18 +1649,105 @@ void LoopIdiomRecognize::buildReducedCRCLoop(
Indexer = Info.ByteOrderSwapped ? 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.ByteOrderSwapped
- ? 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.ByteOrderSwapped);
+ 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.ByteOrderSwapped
+ ? 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.ByteOrderSwapped) {
+ // 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.ByteOrderSwapped),
+ 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.ByteOrderSwapped
+ ? 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.
@@ -1779,6 +1762,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:.*]]
More information about the llvm-commits
mailing list