[LoopIdiomRecognize] Enable clmul optimization for CRC loops (#203405)
The current `optimizeCRCLoop` function always optimizes CRC loops to use a 256-entry Sarwate lookup table to process a byte at a time (except on Hexagon and with optsize). However, some targets are able to process larger chunks of CRC data with carry-less/polynomial multiplication instructions. Implement this approach in IR for such targets using the `llvm.clmul` intrinsic. (Only with optsize for the moment, though.) Like the current CRC loop optimization, this does not apply to the Hexagon target, despite it having a `pmpyw` instruction. Assisted-by: Claude Opus 4.8
This commit is contained in:
parent
6e7ff09291
commit
c7a5b9c0dd
12 changed files with 3519 additions and 335 deletions
|
|
@ -88,6 +88,16 @@ public:
|
|||
LLVM_ABI static CRCTable genSarwateTable(const APInt &GenPoly,
|
||||
bool IsBigEndian);
|
||||
|
||||
/// Auxilary entry point after analysis to generate constants for a GF(2)
|
||||
/// Barrett Reduction.
|
||||
/// Returns a pair of Mu of bitwidth TC+1 and FullGenPoly of bitwidth BW+1.
|
||||
/// Mu is used in the first clmul operation. Mu = floor(x^(BW+TC) / P(x)).
|
||||
/// FullGenPoly is used in the second clmul operation, and is Info.RHS with
|
||||
/// the implied BW'th bit.
|
||||
/// Endianness is accounted for using Info.IsBigEndian.
|
||||
LLVM_ABI static std::pair<APInt, APInt>
|
||||
genBarrettConstants(const PolynomialInfo &Info);
|
||||
|
||||
LLVM_ABI void print(raw_ostream &OS) const;
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
|
|
|
|||
|
|
@ -1193,6 +1193,10 @@ public:
|
|||
/// 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 carry-less multiplication
|
||||
/// instruction.
|
||||
LLVM_ABI bool haveFastClmul(IntegerType *Ty) const;
|
||||
|
||||
/// Return true if the cost of the instruction is too high to speculatively
|
||||
/// execute and should be kept behind a branch.
|
||||
/// This normally just wraps around a getInstructionCost() call, but some
|
||||
|
|
|
|||
|
|
@ -570,6 +570,8 @@ public:
|
|||
|
||||
virtual bool haveFastSqrt(Type *Ty) const { return false; }
|
||||
|
||||
virtual bool haveFastClmul(IntegerType *Ty) const { return false; }
|
||||
|
||||
virtual bool isExpensiveToSpeculativelyExecute(const Instruction *I) const {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -682,6 +682,20 @@ public:
|
|||
TLI->isOperationLegalOrCustom(ISD::FSQRT, VT);
|
||||
}
|
||||
|
||||
bool haveFastClmul(IntegerType *Ty) const override {
|
||||
// FIXME: clmul should really be Promote for any bitwidth under the largest
|
||||
// legal bitwidth for clmul. Using IndexTy instead of Ty is a hack to get
|
||||
// around that shortcoming.
|
||||
IntegerType *IndexTy =
|
||||
DL.getIndexType(Ty->getContext(), DL.getAllocaAddrSpace());
|
||||
if (Ty->getBitWidth() > IndexTy->getBitWidth())
|
||||
return false;
|
||||
|
||||
const TargetLoweringBase *TLI = getTLI();
|
||||
EVT VT = TLI->getValueType(DL, IndexTy);
|
||||
return TLI->isOperationLegalOrCustom(ISD::CLMUL, VT);
|
||||
}
|
||||
|
||||
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override { return true; }
|
||||
|
||||
InstructionCost getFPOpCost(Type *Ty) const override {
|
||||
|
|
|
|||
|
|
@ -376,6 +376,71 @@ CRCTable HashRecognize::genSarwateTable(const APInt &GenPoly,
|
|||
return Table;
|
||||
}
|
||||
|
||||
/// Perform polynomial (GF(2)) floor division. This is based on the
|
||||
/// floor_division(S, P) algorithm in
|
||||
/// https://www.corsix.org/content/barrett-reduction-polynomials. Note that the
|
||||
/// maximum degree of the returned polynomial is
|
||||
/// max(0, deg(Dividend) - deg(Divisor)), but the bit width will be the same as
|
||||
/// that of Dividend.
|
||||
static APInt floorDivideGF2(APInt Dividend, APInt Divisor) {
|
||||
assert(!Divisor.isZero() && "Cannot divide by zero");
|
||||
|
||||
// Extend the divisor bit width to match the dividend.
|
||||
Divisor = Divisor.zext(Dividend.getBitWidth());
|
||||
|
||||
// Note that getActiveBits returns deg+1, but the computation below
|
||||
// still holds.
|
||||
unsigned DivisorActiveBits = Divisor.getActiveBits();
|
||||
|
||||
// Q = 0
|
||||
APInt Quotient = APInt::getZero(Dividend.getBitWidth());
|
||||
// S != 0 and deg(S) >= deg(P)
|
||||
// (S != 0 implied by DivisorActiveBits > 0)
|
||||
while (Dividend.getActiveBits() >= DivisorActiveBits) {
|
||||
// T = S[deg(S)] / P[deg(P)]
|
||||
unsigned Shift = Dividend.getActiveBits() - DivisorActiveBits;
|
||||
// Q = Q + T
|
||||
Quotient.setBit(Shift);
|
||||
// S = S - T * P
|
||||
Dividend ^= Divisor.shl(Shift);
|
||||
}
|
||||
return Quotient;
|
||||
}
|
||||
|
||||
/// Generate the constants for performing a Polynomial (GF(2)) Barrett Reduction
|
||||
/// according to Intel's Fast CRC Computation white paper with some adjustments
|
||||
/// to account for the fact that bit width and trip count can vary.
|
||||
std::pair<APInt, APInt>
|
||||
HashRecognize::genBarrettConstants(const PolynomialInfo &Info) {
|
||||
unsigned BW = Info.RHS.getBitWidth();
|
||||
unsigned TC = Info.TripCount;
|
||||
|
||||
// Recover the full generating polynomial in normal form by reflecting the LE
|
||||
// case and adding the implied x^BW term.
|
||||
// deg(P(x)) = BW due to the implied term, and thus P(x) must fit in exactly
|
||||
// BW+1 bits.
|
||||
APInt FullGenPoly =
|
||||
(Info.IsBigEndian ? Info.RHS : Info.RHS.reverseBits()).zext(BW + 1);
|
||||
FullGenPoly.setBit(BW);
|
||||
|
||||
// Calculate mu = floor(x^(BW+TC) / P(x)).
|
||||
// deg(mu) <= deg(x^(BW+TC)) - deg(P(x)) = BW+TC - BW = TC, and thus mu must
|
||||
// fit in at most TC+1 bits.
|
||||
unsigned DivBW = BW + TC + 1;
|
||||
APInt Mu = floorDivideGF2(APInt::getOneBitSet(DivBW, BW + TC), FullGenPoly)
|
||||
.trunc(TC + 1);
|
||||
|
||||
// In the bit-reflected (little-endian) case, mu and P(x) must be
|
||||
// bit-reflected across their respective widths for the corresponding Barrett
|
||||
// reduction steps.
|
||||
if (!Info.IsBigEndian) {
|
||||
Mu = Mu.reverseBits();
|
||||
FullGenPoly = FullGenPoly.reverseBits();
|
||||
}
|
||||
|
||||
return {Mu, FullGenPoly};
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
|
@ -576,6 +641,13 @@ void HashRecognize::print(raw_ostream &OS) const {
|
|||
}
|
||||
OS.indent(2) << "Computed CRC lookup table:\n";
|
||||
genSarwateTable(Info.RHS, Info.IsBigEndian).print(OS);
|
||||
OS.indent(2) << "Computed CRC Barrett constants:\n";
|
||||
auto [Mu, FullGenPoly] = genBarrettConstants(Info);
|
||||
OS << "Mu = ";
|
||||
Mu.print(OS, false);
|
||||
OS << ", FullGenPoly = ";
|
||||
FullGenPoly.print(OS, false);
|
||||
OS << "\n";
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
|
|
|
|||
|
|
@ -742,6 +742,10 @@ bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
|
|||
return TTIImpl->haveFastSqrt(Ty);
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::haveFastClmul(IntegerType *Ty) const {
|
||||
return TTIImpl->haveFastClmul(Ty);
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::isExpensiveToSpeculativelyExecute(
|
||||
const Instruction *I) const {
|
||||
return TTIImpl->isExpensiveToSpeculativelyExecute(I);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
|
@ -166,6 +167,11 @@ static cl::opt<bool> ForceMemsetPatternIntrinsic(
|
|||
cl::desc("Use memset.pattern intrinsic whenever possible"), cl::init(false),
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool> ForceCRCClmul(
|
||||
"loop-idiom-force-crc-clmul",
|
||||
cl::desc("Use the clmul-based CRC loop optimization whenever possible"),
|
||||
cl::init(false), cl::Hidden);
|
||||
|
||||
extern cl::opt<bool> ProfcheckDisableMetadataFixes;
|
||||
|
||||
} // namespace llvm
|
||||
|
|
@ -259,6 +265,9 @@ private:
|
|||
bool avoidLIRForMultiBlockLoop(bool IsMemset = false,
|
||||
bool IsLoopMemset = false);
|
||||
bool optimizeCRCLoop(const PolynomialInfo &Info);
|
||||
void optimizeCRCLoopUsingClmul(const PolynomialInfo &Info,
|
||||
IntegerType *ClmulTy);
|
||||
void optimizeCRCLoopUsingTableLookup(const PolynomialInfo &Info);
|
||||
|
||||
/// @}
|
||||
/// \name Noncountable Loop Idiom Handling
|
||||
|
|
@ -397,11 +406,10 @@ bool LoopIdiomRecognize::runOnCountableLoop() {
|
|||
MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
|
||||
}
|
||||
|
||||
// Optimize a CRC loop if HashRecognize found one, provided we're not
|
||||
// optimizing for size.
|
||||
if (!DisableLIRP::HashRecognize && !ApplyCodeSizeHeuristics)
|
||||
// Attempt to optimize a CRC loop if one is detected by HashRecognize.
|
||||
if (!DisableLIRP::HashRecognize)
|
||||
if (auto Res = HashRecognize(*CurLoop, *SE).getResult())
|
||||
optimizeCRCLoop(*Res);
|
||||
MadeChange |= optimizeCRCLoop(*Res);
|
||||
|
||||
return MadeChange;
|
||||
}
|
||||
|
|
@ -1582,6 +1590,159 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
|
|||
if (TT.getArch() == Triple::hexagon)
|
||||
return false;
|
||||
|
||||
// In the clmul optimization, the first clmul uses 2*TC bits, and the second
|
||||
// clmul uses CRCBW+TC bits. For simplicity, have both clmuls operate on the
|
||||
// same bit width.
|
||||
unsigned CRCBW = Info.LHS->getType()->getIntegerBitWidth();
|
||||
unsigned ClmulBW = std::max(2 * Info.TripCount, CRCBW + Info.TripCount);
|
||||
auto *ClmulTy = IntegerType::get(Info.LHS->getContext(), ClmulBW);
|
||||
|
||||
// The force-crc-clmul flag should cause the clmul optimization to run
|
||||
// unconditionally.
|
||||
if (ForceCRCClmul) {
|
||||
optimizeCRCLoopUsingClmul(Info, ClmulTy);
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: Once intrinsic cost modeling is more reliable for clmul, that should
|
||||
// be used to determine which optimization to use. Until then, only apply the
|
||||
// clmul optimization when optimizing for size, since a lookup table is not
|
||||
// viable in that case.
|
||||
if (!ApplyCodeSizeHeuristics) {
|
||||
optimizeCRCLoopUsingTableLookup(Info);
|
||||
return true;
|
||||
}
|
||||
|
||||
// The clmul optimization should only be applied if clmul with the required
|
||||
// bit width is a fast operation on the target.
|
||||
// TODO: If clmul exists on the target but not for the required width, it
|
||||
// might be possible to split into multiple iterations of reduction.
|
||||
if (TTI->haveFastClmul(ClmulTy)) {
|
||||
optimizeCRCLoopUsingClmul(Info, ClmulTy);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The algorithm used in this optimization is a Polynomial (GF(2)) Barrett
|
||||
// Reduction based on Intel's "Fast CRC Computation for Generic Polynomials
|
||||
// Using PCLMULQDQ Instruction" white paper (December 2009).
|
||||
void LoopIdiomRecognize::optimizeCRCLoopUsingClmul(const PolynomialInfo &Info,
|
||||
IntegerType *ClmulTy) {
|
||||
Type *CRCTy = Info.LHS->getType();
|
||||
LLVMContext &Ctx = CRCTy->getContext();
|
||||
unsigned CRCBW = CRCTy->getIntegerBitWidth();
|
||||
// The loop's TripCount determines how many bits of the data are processed,
|
||||
// regardless of whether the actual data bit width matches (if auxiliary data
|
||||
// is even used at all).
|
||||
unsigned TC = Info.TripCount;
|
||||
unsigned ClmulBW = ClmulTy->getBitWidth();
|
||||
|
||||
// First, generate the constants required for GF(2) Barrett reduction.
|
||||
auto [Mu, FullGenPoly] = HashRecognize::genBarrettConstants(Info);
|
||||
Value *MuConst = ConstantInt::get(Ctx, Mu.zext(ClmulBW));
|
||||
Value *GenPolyConst = ConstantInt::get(Ctx, FullGenPoly.zext(ClmulBW));
|
||||
|
||||
IRBuilder<> Builder(CurLoop->getLoopPreheader()->getTerminator());
|
||||
|
||||
auto LoTCBits = [TC, &Builder, &Ctx](Value *Op, const Twine &Name) {
|
||||
unsigned OpBW = Op->getType()->getIntegerBitWidth();
|
||||
assert(OpBW >= TC && "Bit width should be at least TripCount");
|
||||
auto *Mask = ConstantInt::get(Ctx, APInt::getLowBitsSet(OpBW, TC));
|
||||
return Builder.CreateAnd(Op, Mask, Name);
|
||||
};
|
||||
|
||||
Value *LHS = Builder.CreateZExt(Info.LHS, ClmulTy, "crc.cast");
|
||||
|
||||
// Based on the Intel white paper, in our case, we have
|
||||
// R(x) = (LHS*x^TC) xor (LHSAux ? getTCBits(LHSAux)*x^CRCBW : 0)
|
||||
// since the CRC loop multiplies LHS by x each iteration, and the x^CRCBW term
|
||||
// of getTCBits(LHSAux) is XORed in for the significant bit check.
|
||||
// Rather than compute the full R(x), we can split it in two: a quotient for
|
||||
// step 1 (floor(R(x)/x^CRCBW)) and a remainder for step 3 (R(x) mod x^CRCBW).
|
||||
//
|
||||
// ClmulMuInput is an evolving variable that will eventually become the part
|
||||
// used in step 1, which can be simplified to
|
||||
// (LHS*x^(TC-CRCBW)) xor (LHSAux ? getTCBits(LHSAux) : 0).
|
||||
// Thanks to restrictions imposed by HashRecognize for big-endian CRC loops,
|
||||
// getTCBits(LHSAux) = LHSAux*x^(TC-CRCBW), so this can be further simplified
|
||||
// to (LHS xor (LHSAux ? LHSAux : 0))*x^(TC-CRCBW).
|
||||
Value *ClmulMuInput = LHS;
|
||||
|
||||
// If auxiliary data is present, XOR it in with the CRC.
|
||||
if (Value *Data = Info.LHSAux) {
|
||||
// This is usually a zext, but DataBW may exceed ClmulBW if both CRCBW and
|
||||
// TC are small enough.
|
||||
Data = Builder.CreateZExtOrTrunc(Data, ClmulTy, "data.cast");
|
||||
|
||||
ClmulMuInput = Builder.CreateXor(ClmulMuInput, Data, "xor.crc.data");
|
||||
}
|
||||
|
||||
// Align the current CRC with TripCount (multiply or divide by x^(TC-CRCBW)).
|
||||
if (Info.IsBigEndian && TC != CRCBW) {
|
||||
ClmulMuInput =
|
||||
TC > CRCBW
|
||||
? Builder.CreateShl(ClmulMuInput, TC - CRCBW, "crc.align.tc")
|
||||
: Builder.CreateLShr(ClmulMuInput, CRCBW - TC, "crc.align.tc");
|
||||
}
|
||||
|
||||
// Zero out any bits above (TC-1) for calculation since the original loop
|
||||
// doesn't use them in the significant bit checks.
|
||||
ClmulMuInput = LoTCBits(ClmulMuInput, "crc.tcbits");
|
||||
|
||||
// Step 1: T1(x) = floor(R(x)/x^CRCBW) * mu
|
||||
// Input is TC bits and mu is TC+1 bits, so result will be 2*TC bits.
|
||||
Value *ClmulMu = Builder.CreateBinaryIntrinsic(
|
||||
Intrinsic::clmul, ClmulMuInput, MuConst, /*FMFSource=*/{}, "clmul.mu");
|
||||
|
||||
// Calculate floor(T1(x)/x^TC) for step 2.
|
||||
Value *ClmulGPInput = Info.IsBigEndian
|
||||
? Builder.CreateLShr(ClmulMu, TC, "quot.lshr")
|
||||
: LoTCBits(ClmulMu, "quot.mask");
|
||||
|
||||
// Step 2: T2(x) = floor(T1(x)/x^TC) * P(x)
|
||||
// Input is TC bits and P(x) is CRCBW+1 bits, so result will be CRCBW+TC bits.
|
||||
Value *ClmulGP = Builder.CreateBinaryIntrinsic(Intrinsic::clmul, ClmulGPInput,
|
||||
GenPolyConst,
|
||||
/*FMFSource=*/{}, "clmul.gp");
|
||||
|
||||
// Calculate the least significant part of R(x) for step 3 as specified above.
|
||||
// R(x) mod x^CRCBW = LHS*x^TC mod x^CRCBW, though the (mod x^CRCBW) is
|
||||
// handled later on when truncating back to CRCBW for ComputedValue.
|
||||
Value *CRCAlignClmul =
|
||||
Info.IsBigEndian ? Builder.CreateShl(LHS, TC, "crc.shl") : LHS;
|
||||
|
||||
// Step 3: C(x) = (R(x) xor T2(x)) mod x^CRCBW
|
||||
Value *CRCNext = Builder.CreateXor(CRCAlignClmul, ClmulGP, "xor.crc.mult");
|
||||
if (!Info.IsBigEndian)
|
||||
CRCNext = Builder.CreateLShr(CRCNext, TC, "crc.lshr");
|
||||
|
||||
// Bring the result back down the the CRC bit width.
|
||||
CRCNext = Builder.CreateTrunc(CRCNext, CRCTy, "crc.next");
|
||||
|
||||
// Replace the result of the loop with the new computed CRC value.
|
||||
Info.ComputedValue->replaceUsesOutsideBlock(CRCNext, CurLoop->getLoopLatch());
|
||||
|
||||
// Finally, clean up the loop as much as possible so it can be trivially
|
||||
// deleted.
|
||||
{
|
||||
for (PHINode &PN : make_early_inc_range(CurLoop->getHeader()->phis())) {
|
||||
PN.replaceAllUsesWith(PoisonValue::get(PN.getType()));
|
||||
RecursivelyDeleteDeadPHINode(&PN);
|
||||
}
|
||||
// Replace the exit condition with constant true/false to always cause a
|
||||
// branch to the exit block.
|
||||
deleteDeadInstruction(CurLoop->getLatchCmpInst());
|
||||
auto *BrInst = cast<CondBrInst>(CurLoop->getLoopLatch()->getTerminator());
|
||||
BrInst->setCondition(ConstantInt::getBool(
|
||||
Ctx, BrInst->getSuccessor(0) == CurLoop->getExitBlock()));
|
||||
SE->forgetLoop(CurLoop);
|
||||
}
|
||||
}
|
||||
|
||||
void LoopIdiomRecognize::optimizeCRCLoopUsingTableLookup(
|
||||
const PolynomialInfo &Info) {
|
||||
// First, create a new GlobalVariable corresponding to the
|
||||
// Sarwate-lookup-table.
|
||||
Type *CRCTy = Info.LHS->getType();
|
||||
|
|
@ -1592,9 +1753,9 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
|
|||
[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");
|
||||
GlobalVariable *GV = new GlobalVariable(
|
||||
*CurLoop->getHeader()->getModule(), ConstArray->getType(), true,
|
||||
GlobalValue::PrivateLinkage, ConstArray, ".crctable");
|
||||
|
||||
PHINode *IV = CurLoop->getCanonicalInductionVariable();
|
||||
SmallVector<PHINode *, 2> Cleanup;
|
||||
|
|
@ -1718,7 +1879,6 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
|
|||
RecursivelyDeleteDeadPHINode(PN);
|
||||
SE->forgetLoop(CurLoop);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoopIdiomRecognize::runOnNoncountableLoop() {
|
||||
|
|
|
|||
|
|
@ -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: Mu = 511, FullGenPoly = 81923
|
||||
;
|
||||
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: Mu = 511, FullGenPoly = 81923
|
||||
;
|
||||
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: Mu = 114687, FullGenPoly = 81923
|
||||
;
|
||||
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: Mu = 24423, FullGenPoly = 59
|
||||
;
|
||||
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: Mu = 273, FullGenPoly = 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: Mu = 273, FullGenPoly = 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: Mu = 273, FullGenPoly = 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: Mu = 284, FullGenPoly = 285
|
||||
;
|
||||
entry:
|
||||
br label %outer.loop
|
||||
|
|
@ -380,6 +396,54 @@ exit: ; preds = %outer.loop
|
|||
ret i8 %crc.outer
|
||||
}
|
||||
|
||||
define i16 @crc16.be.tc16(i16 %msg, i16 %checksum) {
|
||||
; CHECK-LABEL: 'crc16.be.tc16'
|
||||
; CHECK-NEXT: Found big-endian CRC-16 loop with trip count 16
|
||||
; CHECK-NEXT: Initial CRC: i16 %checksum
|
||||
; CHECK-NEXT: Generating polynomial: 4129
|
||||
; CHECK-NEXT: Computed CRC: %crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
|
||||
; CHECK-NEXT: Auxiliary data: i16 %msg
|
||||
; CHECK-NEXT: Computed CRC lookup table:
|
||||
; CHECK-NEXT: 0 4129 8258 12387 16516 20645 24774 28903 33032 37161 41290 45419 49548 53677 57806 61935
|
||||
; CHECK-NEXT: 4657 528 12915 8786 21173 17044 29431 25302 37689 33560 45947 41818 54205 50076 62463 58334
|
||||
; CHECK-NEXT: 9314 13379 1056 5121 25830 29895 17572 21637 42346 46411 34088 38153 58862 62927 50604 54669
|
||||
; CHECK-NEXT: 13907 9842 5649 1584 30423 26358 22165 18100 46939 42874 38681 34616 63455 59390 55197 51132
|
||||
; CHECK-NEXT: 18628 22757 26758 30887 2112 6241 10242 14371 51660 55789 59790 63919 35144 39273 43274 47403
|
||||
; CHECK-NEXT: 23285 19156 31415 27286 6769 2640 14899 10770 56317 52188 64447 60318 39801 35672 47931 43802
|
||||
; CHECK-NEXT: 27814 31879 19684 23749 11298 15363 3168 7233 60846 64911 52716 56781 44330 48395 36200 40265
|
||||
; CHECK-NEXT: 32407 28342 24277 20212 15891 11826 7761 3696 65439 61374 57309 53244 48923 44858 40793 36728
|
||||
; CHECK-NEXT: 37256 33193 45514 41451 53516 49453 61774 57711 4224 161 12482 8419 20484 16421 28742 24679
|
||||
; CHECK-NEXT: 33721 37784 41979 46042 49981 54044 58239 62302 689 4752 8947 13010 16949 21012 25207 29270
|
||||
; CHECK-NEXT: 46570 42443 38312 34185 62830 58703 54572 50445 13538 9411 5280 1153 29798 25671 21540 17413
|
||||
; CHECK-NEXT: 42971 47098 34713 38840 59231 63358 50973 55100 9939 14066 1681 5808 26199 30326 17941 22068
|
||||
; CHECK-NEXT: 55628 51565 63758 59695 39368 35305 47498 43435 22596 18533 30726 26663 6336 2273 14466 10403
|
||||
; CHECK-NEXT: 52093 56156 60223 64286 35833 39896 43963 48026 19061 23124 27191 31254 2801 6864 10931 14994
|
||||
; CHECK-NEXT: 64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
|
||||
; CHECK-NEXT: 61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
|
||||
; CHECK-NEXT: Computed CRC Barrett constants:
|
||||
; CHECK-NEXT: Mu = 69936, FullGenPoly = 69665
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%xor.crc.data = xor i16 %crc, %data
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i16 %xor.crc.data, 0
|
||||
%crc.shl = shl i16 %crc, 1
|
||||
%crc.xor = xor i16 %crc.shl, 4129
|
||||
%crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
|
||||
; CHECK-LABEL: 'crc16.be.tc8.misalign'
|
||||
; CHECK-NEXT: Found big-endian CRC-16 loop with trip count 8
|
||||
|
|
@ -403,6 +467,8 @@ define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) {
|
|||
; CHECK-NEXT: 52093 56156 60223 64286 35833 39896 43963 48026 19061 23124 27191 31254 2801 6864 10931 14994
|
||||
; CHECK-NEXT: 64814 60687 56684 52557 48554 44427 40424 36297 31782 27655 23652 19525 15522 11395 7392 3265
|
||||
; CHECK-NEXT: 61215 65342 53085 57212 44955 49082 36825 40952 28183 32310 20053 24180 11923 16050 3793 7920
|
||||
; CHECK-NEXT: Computed CRC Barrett constants:
|
||||
; CHECK-NEXT: Mu = 273, FullGenPoly = 69665
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
|
@ -426,6 +492,104 @@ exit: ; preds = %loop
|
|||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) {
|
||||
; CHECK-LABEL: 'crc8.be.tc16.misalign'
|
||||
; CHECK-NEXT: Found big-endian CRC-8 loop with trip count 16
|
||||
; CHECK-NEXT: Initial CRC: i8 %checksum
|
||||
; CHECK-NEXT: Generating polynomial: 29
|
||||
; CHECK-NEXT: Computed CRC: %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
; CHECK-NEXT: Auxiliary data: i16 %msg
|
||||
; CHECK-NEXT: Computed CRC lookup table:
|
||||
; CHECK-NEXT: 0 29 58 39 116 105 78 83 232 245 210 207 156 129 166 187
|
||||
; CHECK-NEXT: 205 208 247 234 185 164 131 158 37 56 31 2 81 76 107 118
|
||||
; CHECK-NEXT: 135 154 189 160 243 238 201 212 111 114 85 72 27 6 33 60
|
||||
; CHECK-NEXT: 74 87 112 109 62 35 4 25 162 191 152 133 214 203 236 241
|
||||
; CHECK-NEXT: 19 14 41 52 103 122 93 64 251 230 193 220 143 146 181 168
|
||||
; CHECK-NEXT: 222 195 228 249 170 183 144 141 54 43 12 17 66 95 120 101
|
||||
; CHECK-NEXT: 148 137 174 179 224 253 218 199 124 97 70 91 8 21 50 47
|
||||
; CHECK-NEXT: 89 68 99 126 45 48 23 10 177 172 139 150 197 216 255 226
|
||||
; CHECK-NEXT: 38 59 28 1 82 79 104 117 206 211 244 233 186 167 128 157
|
||||
; CHECK-NEXT: 235 246 209 204 159 130 165 184 3 30 57 36 119 106 77 80
|
||||
; CHECK-NEXT: 161 188 155 134 213 200 239 242 73 84 115 110 61 32 7 26
|
||||
; CHECK-NEXT: 108 113 86 75 24 5 34 63 132 153 190 163 240 237 202 215
|
||||
; CHECK-NEXT: 53 40 15 18 65 92 123 102 221 192 231 250 169 180 147 142
|
||||
; CHECK-NEXT: 248 229 194 223 140 145 182 171 16 13 42 55 100 121 94 67
|
||||
; CHECK-NEXT: 178 175 136 149 198 219 252 225 90 71 96 125 46 51 20 9
|
||||
; CHECK-NEXT: 127 98 69 88 11 22 49 44 151 138 173 176 227 254 217 196
|
||||
; CHECK-NEXT: Computed CRC Barrett constants:
|
||||
; CHECK-NEXT: Mu = 72779, FullGenPoly = 285
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) {
|
||||
; CHECK-LABEL: 'crc8.be.tc8.data16.misalign'
|
||||
; CHECK-NEXT: Found big-endian CRC-8 loop with trip count 8
|
||||
; CHECK-NEXT: Initial CRC: i8 %checksum
|
||||
; CHECK-NEXT: Generating polynomial: 29
|
||||
; CHECK-NEXT: Computed CRC: %crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
; CHECK-NEXT: Auxiliary data: i16 %msg
|
||||
; CHECK-NEXT: Computed CRC lookup table:
|
||||
; CHECK-NEXT: 0 29 58 39 116 105 78 83 232 245 210 207 156 129 166 187
|
||||
; CHECK-NEXT: 205 208 247 234 185 164 131 158 37 56 31 2 81 76 107 118
|
||||
; CHECK-NEXT: 135 154 189 160 243 238 201 212 111 114 85 72 27 6 33 60
|
||||
; CHECK-NEXT: 74 87 112 109 62 35 4 25 162 191 152 133 214 203 236 241
|
||||
; CHECK-NEXT: 19 14 41 52 103 122 93 64 251 230 193 220 143 146 181 168
|
||||
; CHECK-NEXT: 222 195 228 249 170 183 144 141 54 43 12 17 66 95 120 101
|
||||
; CHECK-NEXT: 148 137 174 179 224 253 218 199 124 97 70 91 8 21 50 47
|
||||
; CHECK-NEXT: 89 68 99 126 45 48 23 10 177 172 139 150 197 216 255 226
|
||||
; CHECK-NEXT: 38 59 28 1 82 79 104 117 206 211 244 233 186 167 128 157
|
||||
; CHECK-NEXT: 235 246 209 204 159 130 165 184 3 30 57 36 119 106 77 80
|
||||
; CHECK-NEXT: 161 188 155 134 213 200 239 242 73 84 115 110 61 32 7 26
|
||||
; CHECK-NEXT: 108 113 86 75 24 5 34 63 132 153 190 163 240 237 202 215
|
||||
; CHECK-NEXT: 53 40 15 18 65 92 123 102 221 192 231 250 169 180 147 142
|
||||
; CHECK-NEXT: 248 229 194 223 140 145 182 171 16 13 42 55 100 121 94 67
|
||||
; CHECK-NEXT: 178 175 136 149 198 219 252 225 90 71 96 125 46 51 20 9
|
||||
; CHECK-NEXT: 127 98 69 88 11 22 49 44 151 138 173 176 227 254 217 196
|
||||
; CHECK-NEXT: Computed CRC Barrett constants:
|
||||
; CHECK-NEXT: Mu = 284, FullGenPoly = 285
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) {
|
||||
; CHECK-LABEL: 'crc32.le.tc8.data32'
|
||||
; CHECK-NEXT: Found little-endian CRC-32 loop with trip count 8
|
||||
|
|
@ -450,6 +614,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: Mu = 273, FullGenPoly = 67601
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
|
@ -473,6 +639,56 @@ exit: ; preds = %loop
|
|||
ret i32 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) {
|
||||
; CHECK-LABEL: 'crc8.le.tc8.data32'
|
||||
; CHECK-NEXT: Found little-endian CRC-8 loop with trip count 8
|
||||
; CHECK-NEXT: Initial CRC: i8 %checksum
|
||||
; CHECK-NEXT: Generating polynomial: 59
|
||||
; CHECK-NEXT: Computed CRC: %crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
|
||||
; CHECK-NEXT: Auxiliary data: i32 %msg
|
||||
; CHECK-NEXT: Computed CRC lookup table:
|
||||
; CHECK-NEXT: 0 16 32 48 55 39 23 7 25 9 57 41 46 62 14 30
|
||||
; CHECK-NEXT: 50 34 18 2 5 21 37 53 43 59 11 27 28 12 60 44
|
||||
; CHECK-NEXT: 19 3 51 35 36 52 4 20 10 26 42 58 61 45 29 13
|
||||
; CHECK-NEXT: 33 49 1 17 22 6 54 38 56 40 24 8 15 31 47 63
|
||||
; CHECK-NEXT: 38 54 6 22 17 1 49 33 63 47 31 15 8 24 40 56
|
||||
; CHECK-NEXT: 20 4 52 36 35 51 3 19 13 29 45 61 58 42 26 10
|
||||
; CHECK-NEXT: 53 37 21 5 2 18 34 50 44 60 12 28 27 11 59 43
|
||||
; CHECK-NEXT: 7 23 39 55 48 32 16 0 30 14 62 46 41 57 9 25
|
||||
; CHECK-NEXT: 59 43 27 11 12 28 44 60 34 50 2 18 21 5 53 37
|
||||
; CHECK-NEXT: 9 25 41 57 62 46 30 14 16 0 48 32 39 55 7 23
|
||||
; CHECK-NEXT: 40 56 8 24 31 15 63 47 49 33 17 1 6 22 38 54
|
||||
; CHECK-NEXT: 26 10 58 42 45 61 13 29 3 19 35 51 52 36 20 4
|
||||
; CHECK-NEXT: 29 13 61 45 42 58 10 26 4 20 36 52 51 35 19 3
|
||||
; CHECK-NEXT: 47 63 15 31 24 8 56 40 54 38 22 6 1 17 33 49
|
||||
; CHECK-NEXT: 14 30 46 62 57 41 25 9 23 7 55 39 32 48 0 16
|
||||
; CHECK-NEXT: 60 44 28 12 11 27 43 59 37 53 5 21 18 2 50 34
|
||||
; CHECK-NEXT: Computed CRC Barrett constants:
|
||||
; CHECK-NEXT: Mu = 107, FullGenPoly = 119
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%data.trunc = trunc i32 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%sb.crc.data = and i8 %xor.crc.data, 1
|
||||
%check.sb = icmp eq i8 %sb.crc.data, 0
|
||||
%crc.lshr = lshr i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.lshr, 59
|
||||
%crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%data.next = lshr i32 %data, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i16 @crc16.be.tc8.zext.data(i8 %msg, i16 %checksum) {
|
||||
; CHECK-LABEL: 'crc16.be.tc8.zext.data'
|
||||
; CHECK-NEXT: Found big-endian CRC-16 loop with trip count 8
|
||||
|
|
@ -496,6 +712,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: Mu = 257, FullGenPoly = 65794
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
|
|
|||
|
|
@ -0,0 +1,707 @@
|
|||
; 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
|
||||
|
||||
define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
|
||||
; NOAES-NEXT: [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
|
||||
; NOAES-NEXT: [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = lshr i8 [[DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
|
||||
; NOAES-NEXT: [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
|
||||
; NOAES-NEXT: [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[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: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i24
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
|
||||
; AES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i24 [[XOR_CRC_DATA]], 255
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_TCBITS]], i24 511)
|
||||
; AES-NEXT: [[QUOT_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_MASK]], i24 81923)
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_LSHR1:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
|
||||
; AES-NEXT: [[CRC_NEXT2:%.*]] = trunc i24 [[CRC_LSHR1]] to i16
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
|
||||
; AES-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
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.tc16(i16 %msg, i16 %checksum) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
|
||||
; NOAES-NEXT: [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = lshr i16 [[DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[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: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i32
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 114687)
|
||||
; AES-NEXT: [[QUOT_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_MASK]], i32 81923)
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_LSHR2:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[CRC_LSHR2]] to i16
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[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) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOAES-NEXT: [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = lshr i16 [[DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[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: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i32
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 24423)
|
||||
; AES-NEXT: [[QUOT_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_MASK]], i32 59)
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_LSHR2:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[CRC_LSHR2]] to i8
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; AES-NEXT: 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.tc16(i16 %msg, i16 %checksum) optsize {
|
||||
; NOAES-LABEL: define i16 @crc16.be.tc16(
|
||||
; NOAES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOAES-NEXT: [[ENTRY:.*]]:
|
||||
; NOAES-NEXT: br label %[[LOOP:.*]]
|
||||
; NOAES: [[LOOP]]:
|
||||
; NOAES-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp sge i16 [[XOR_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; AES-LABEL: define i16 @crc16.be.tc16(
|
||||
; AES-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; AES-NEXT: [[ENTRY:.*:]]
|
||||
; AES-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i32
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 69936)
|
||||
; AES-NEXT: [[QUOT_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LSHR]], i32 69665)
|
||||
; AES-NEXT: [[CRC_SHL2:%.*]] = shl i32 [[CRC_CAST]], 16
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; AES-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%xor.crc.data = xor i16 %crc, %data
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i16 %xor.crc.data, 0
|
||||
%crc.shl = shl i16 %crc, 1
|
||||
%crc.xor = xor i16 %crc.shl, 4129
|
||||
%crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) optsize {
|
||||
; NOAES-LABEL: define i16 @crc16.be.tc8.misalign(
|
||||
; NOAES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOAES-NEXT: [[ENTRY:.*]]:
|
||||
; NOAES-NEXT: br label %[[LOOP:.*]]
|
||||
; NOAES: [[LOOP]]:
|
||||
; NOAES-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
|
||||
; NOAES-NEXT: [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = shl i8 [[DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_DATA_CRC]], 0
|
||||
; NOAES-NEXT: [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
|
||||
; NOAES-NEXT: [[XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; AES-LABEL: define i16 @crc16.be.tc8.misalign(
|
||||
; AES-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; AES-NEXT: [[ENTRY:.*:]]
|
||||
; AES-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i24
|
||||
; AES-NEXT: [[CRC_ALIGN_TC:%.*]] = lshr i24 [[CRC_CAST]], 8
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i24 [[CRC_ALIGN_TC]], 255
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_TCBITS]], i24 273)
|
||||
; AES-NEXT: [[QUOT_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LSHR]], i24 69665)
|
||||
; AES-NEXT: [[CRC_SHL1:%.*]] = shl i24 [[CRC_CAST]], 8
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_SHL1]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_NEXT2:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
|
||||
; AES-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%crc.trunc = trunc i16 %crc to i8
|
||||
%xor.data.crc = xor i8 %data, %crc.trunc
|
||||
%data.next = shl i8 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.data.crc, 0
|
||||
%crc.shl = shl i16 %crc, 1
|
||||
%xor = xor i16 %crc.shl, 4129
|
||||
%crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) optsize {
|
||||
; NOAES-LABEL: define i8 @crc8.be.tc16.misalign(
|
||||
; NOAES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOAES-NEXT: [[ENTRY:.*]]:
|
||||
; NOAES-NEXT: br label %[[LOOP:.*]]
|
||||
; NOAES: [[LOOP]]:
|
||||
; NOAES-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_SHL]], i8 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; AES-LABEL: define i8 @crc8.be.tc16.misalign(
|
||||
; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; AES-NEXT: [[ENTRY:.*:]]
|
||||
; AES-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i32
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_ALIGN_TC:%.*]] = shl i32 [[XOR_CRC_DATA1]], 8
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[CRC_ALIGN_TC]], 65535
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 72779)
|
||||
; AES-NEXT: [[QUOT_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LSHR]], i32 285)
|
||||
; AES-NEXT: [[CRC_SHL2:%.*]] = shl i32 [[CRC_CAST]], 16
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; AES-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) optsize {
|
||||
; NOAES-LABEL: define i8 @crc8.be.tc8.data16.misalign(
|
||||
; NOAES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOAES-NEXT: [[ENTRY:.*]]:
|
||||
; NOAES-NEXT: br label %[[LOOP:.*]]
|
||||
; NOAES: [[LOOP]]:
|
||||
; NOAES-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_SHL]], i8 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; AES-LABEL: define i8 @crc8.be.tc8.data16.misalign(
|
||||
; AES-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; AES-NEXT: [[ENTRY:.*:]]
|
||||
; AES-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i16
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_CAST]], [[MSG]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i16 [[XOR_CRC_DATA1]], 255
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_TCBITS]], i16 284)
|
||||
; AES-NEXT: [[QUOT_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LSHR]], i16 285)
|
||||
; AES-NEXT: [[CRC_SHL2:%.*]] = shl i16 [[CRC_CAST]], 8
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; AES-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; NOAES-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; AES-LABEL: define i32 @crc32.le.tc8.data32(
|
||||
; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; AES-NEXT: [[ENTRY:.*:]]
|
||||
; AES-NEXT: [[CRC_CAST:%.*]] = zext i32 [[CHECKSUM]] to i40
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = zext i32 [[MSG]] to i40
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i40 [[XOR_CRC_DATA1]], 255
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[CRC_TCBITS]], i40 273)
|
||||
; AES-NEXT: [[QUOT_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_MASK]], i40 67601)
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_LSHR2:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i40 [[CRC_LSHR2]] to i32
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[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 i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) optsize {
|
||||
; NOAES-LABEL: define i8 @crc8.le.tc8.data32(
|
||||
; NOAES-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; NOAES-NEXT: [[ENTRY:.*]]:
|
||||
; NOAES-NEXT: br label %[[LOOP:.*]]
|
||||
; NOAES: [[LOOP]]:
|
||||
; NOAES-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA_TRUNC:%.*]] = trunc i32 [[DATA]] to i8
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOAES-NEXT: [[SB_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[SB_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 59
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; AES-LABEL: define i8 @crc8.le.tc8.data32(
|
||||
; AES-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; AES-NEXT: [[ENTRY:.*:]]
|
||||
; AES-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i16
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = trunc i32 [[MSG]] to i16
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i16 [[XOR_CRC_DATA1]], 255
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_TCBITS]], i16 107)
|
||||
; AES-NEXT: [[QUOT_MASK:%.*]] = and i16 [[CLMUL_MU]], 255
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_MASK]], i16 119)
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_LSHR2:%.*]] = lshr i16 [[XOR_CRC_MULT]], 8
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i16 [[CRC_LSHR2]] to i8
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; AES-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%data.trunc = trunc i32 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%sb.crc.data = and i8 %xor.crc.data, 1
|
||||
%check.sb = icmp eq i8 %sb.crc.data, 0
|
||||
%crc.lshr = lshr i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.lshr, 59
|
||||
%crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%data.next = lshr i32 %data, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i32 @crc32.le.tc32(i32 %checksum, i32 %msg) optsize {
|
||||
; NOAES-LABEL: define i32 @crc32.le.tc32(
|
||||
; NOAES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; NOAES-NEXT: [[ENTRY:.*]]:
|
||||
; NOAES-NEXT: br label %[[LOOP:.*]]
|
||||
; NOAES: [[LOOP]]:
|
||||
; NOAES-NEXT: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; NOAES-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; NOAES-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; NOAES-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; NOAES-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; NOAES-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; NOAES-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOAES-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOAES-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 31
|
||||
; NOAES-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOAES: [[EXIT]]:
|
||||
; NOAES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOAES-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; AES-LABEL: define i32 @crc32.le.tc32(
|
||||
; AES-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; AES-NEXT: [[ENTRY:.*:]]
|
||||
; AES-NEXT: [[CRC_CAST:%.*]] = zext i32 [[CHECKSUM]] to i64
|
||||
; AES-NEXT: [[DATA_CAST:%.*]] = zext i32 [[MSG]] to i64
|
||||
; AES-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; AES-NEXT: [[CRC_TCBITS:%.*]] = and i64 [[XOR_CRC_DATA1]], 4294967295
|
||||
; AES-NEXT: [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[CRC_TCBITS]], i64 4770502929)
|
||||
; AES-NEXT: [[QUOT_MASK:%.*]] = and i64 [[CLMUL_MU]], 4294967295
|
||||
; AES-NEXT: [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_MASK]], i64 67601)
|
||||
; AES-NEXT: [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; AES-NEXT: [[CRC_LSHR2:%.*]] = lshr i64 [[XOR_CRC_MULT]], 32
|
||||
; AES-NEXT: [[CRC_NEXT3:%.*]] = trunc i64 [[CRC_LSHR2]] to i32
|
||||
; AES-NEXT: br label %[[LOOP:.*]]
|
||||
; AES: [[LOOP]]:
|
||||
; AES-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; AES: [[EXIT]]:
|
||||
; AES-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[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, 31
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i32 %crc.next
|
||||
}
|
||||
|
||||
define i64 @crc64.le.tc64(i64 %checksum, i64 %msg) optsize {
|
||||
; ALL-LABEL: define i64 @crc64.le.tc64(
|
||||
; ALL-SAME: i64 [[CHECKSUM:%.*]], i64 [[MSG:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; ALL-NEXT: [[ENTRY:.*]]:
|
||||
; ALL-NEXT: br label %[[LOOP:.*]]
|
||||
; ALL: [[LOOP]]:
|
||||
; ALL-NEXT: [[CRC:%.*]] = phi i64 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[DATA:%.*]] = phi i64 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i64 [[CRC]], [[DATA]]
|
||||
; ALL-NEXT: [[SB_CRC_DATA:%.*]] = and i64 [[XOR_CRC_DATA]], 1
|
||||
; ALL-NEXT: [[CHECK_SB:%.*]] = icmp eq i64 [[SB_CRC_DATA]], 0
|
||||
; ALL-NEXT: [[CRC_LSHR:%.*]] = lshr i64 [[CRC]], 1
|
||||
; ALL-NEXT: [[CRC_XOR:%.*]] = xor i64 [[CRC_LSHR]], 33800
|
||||
; ALL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i64 [[CRC_LSHR]], i64 [[CRC_XOR]]
|
||||
; ALL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; ALL-NEXT: [[DATA_NEXT]] = lshr i64 [[DATA]], 1
|
||||
; ALL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 63
|
||||
; ALL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ALL: [[EXIT]]:
|
||||
; ALL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i64 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; ALL-NEXT: ret i64 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%crc = phi i64 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i64 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%xor.crc.data = xor i64 %crc, %data
|
||||
%sb.crc.data = and i64 %xor.crc.data, 1
|
||||
%check.sb = icmp eq i64 %sb.crc.data, 0
|
||||
%crc.lshr = lshr i64 %crc, 1
|
||||
%crc.xor = xor i64 %crc.lshr, 33800
|
||||
%crc.next = select i1 %check.sb, i64 %crc.lshr, i64 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%data.next = lshr i64 %data, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 63
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i64 %crc.next
|
||||
}
|
||||
;.
|
||||
; NOAES: attributes #[[ATTR0]] = { optsize "target-features"="-aes" }
|
||||
;.
|
||||
; AES: attributes #[[ATTR0]] = { optsize "target-features"="+aes" }
|
||||
; AES: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
;.
|
||||
761
llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
Normal file
761
llvm/test/Transforms/LoopIdiom/RISCV/cyclic-redundancy-check.ll
Normal file
|
|
@ -0,0 +1,761 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
|
||||
; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,NOZBC,NOZBC32 %s
|
||||
; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=-zbc -S %s | FileCheck --check-prefixes=ALL,NOZBC,NOZBC64 %s
|
||||
; RUN: opt -passes=loop-idiom -mtriple=riscv32 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ZBC,ZBC32 %s
|
||||
; RUN: opt -passes=loop-idiom -mtriple=riscv64 -mattr=+zbc -S %s | FileCheck --check-prefixes=ALL,ZBC,ZBC64 %s
|
||||
|
||||
define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) optsize {
|
||||
; NOZBC-LABEL: define i16 @crc16.le.tc8(
|
||||
; NOZBC-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
|
||||
; NOZBC-NEXT: [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
|
||||
; NOZBC-NEXT: [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = lshr i8 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
|
||||
; NOZBC-NEXT: [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i16 @crc16.le.tc8(
|
||||
; ZBC-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i24
|
||||
; ZBC-NEXT: [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
|
||||
; ZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i24 [[XOR_CRC_DATA]], 255
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_TCBITS]], i24 511)
|
||||
; ZBC-NEXT: [[QUOT_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_MASK]], i24 81923)
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_LSHR1:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
|
||||
; ZBC-NEXT: [[CRC_NEXT2:%.*]] = trunc i24 [[CRC_LSHR1]] to i16
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
|
||||
; ZBC-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
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.tc16(i16 %msg, i16 %checksum) optsize {
|
||||
; NOZBC-LABEL: define i16 @crc16.le.tc16(
|
||||
; NOZBC-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
|
||||
; NOZBC-NEXT: [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = lshr i16 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i16 @crc16.le.tc16(
|
||||
; ZBC-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i32
|
||||
; ZBC-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; ZBC-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 114687)
|
||||
; ZBC-NEXT: [[QUOT_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_MASK]], i32 81923)
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_LSHR2:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
|
||||
; ZBC-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[CRC_LSHR2]] to i16
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; ZBC-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) optsize {
|
||||
; NOZBC-LABEL: define i8 @crc8.le.tc16(
|
||||
; NOZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOZBC-NEXT: [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = lshr i16 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i8 @crc8.le.tc16(
|
||||
; ZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i32
|
||||
; ZBC-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; ZBC-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 24423)
|
||||
; ZBC-NEXT: [[QUOT_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_MASK]], i32 59)
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_LSHR2:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
|
||||
; ZBC-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[CRC_LSHR2]] to i8
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; ZBC-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.tc16(i16 %msg, i16 %checksum) optsize {
|
||||
; NOZBC-LABEL: define i16 @crc16.be.tc16(
|
||||
; NOZBC-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp sge i16 [[XOR_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i16 @crc16.be.tc16(
|
||||
; ZBC-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i32
|
||||
; ZBC-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; ZBC-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 69936)
|
||||
; ZBC-NEXT: [[QUOT_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LSHR]], i32 69665)
|
||||
; ZBC-NEXT: [[CRC_SHL2:%.*]] = shl i32 [[CRC_CAST]], 16
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; ZBC-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%xor.crc.data = xor i16 %crc, %data
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i16 %xor.crc.data, 0
|
||||
%crc.shl = shl i16 %crc, 1
|
||||
%crc.xor = xor i16 %crc.shl, 4129
|
||||
%crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) optsize {
|
||||
; NOZBC-LABEL: define i16 @crc16.be.tc8.misalign(
|
||||
; NOZBC-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
|
||||
; NOZBC-NEXT: [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = shl i8 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_DATA_CRC]], 0
|
||||
; NOZBC-NEXT: [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i16 @crc16.be.tc8.misalign(
|
||||
; ZBC-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i24
|
||||
; ZBC-NEXT: [[CRC_ALIGN_TC:%.*]] = lshr i24 [[CRC_CAST]], 8
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i24 [[CRC_ALIGN_TC]], 255
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_TCBITS]], i24 273)
|
||||
; ZBC-NEXT: [[QUOT_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LSHR]], i24 69665)
|
||||
; ZBC-NEXT: [[CRC_SHL1:%.*]] = shl i24 [[CRC_CAST]], 8
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_SHL1]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_NEXT2:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
|
||||
; ZBC-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%crc.trunc = trunc i16 %crc to i8
|
||||
%xor.data.crc = xor i8 %data, %crc.trunc
|
||||
%data.next = shl i8 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.data.crc, 0
|
||||
%crc.shl = shl i16 %crc, 1
|
||||
%xor = xor i16 %crc.shl, 4129
|
||||
%crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) optsize {
|
||||
; NOZBC-LABEL: define i8 @crc8.be.tc16.misalign(
|
||||
; NOZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_SHL]], i8 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i8 @crc8.be.tc16.misalign(
|
||||
; ZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i32
|
||||
; ZBC-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; ZBC-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC-NEXT: [[CRC_ALIGN_TC:%.*]] = shl i32 [[XOR_CRC_DATA1]], 8
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[CRC_ALIGN_TC]], 65535
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 72779)
|
||||
; ZBC-NEXT: [[QUOT_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LSHR]], i32 285)
|
||||
; ZBC-NEXT: [[CRC_SHL2:%.*]] = shl i32 [[CRC_CAST]], 16
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; ZBC-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) optsize {
|
||||
; NOZBC-LABEL: define i8 @crc8.be.tc8.data16.misalign(
|
||||
; NOZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_SHL]], i8 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i8 @crc8.be.tc8.data16.misalign(
|
||||
; ZBC-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i16
|
||||
; ZBC-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_CAST]], [[MSG]]
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i16 [[XOR_CRC_DATA1]], 255
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_TCBITS]], i16 284)
|
||||
; ZBC-NEXT: [[QUOT_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LSHR]], i16 285)
|
||||
; ZBC-NEXT: [[CRC_SHL2:%.*]] = shl i16 [[CRC_CAST]], 8
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_NEXT3:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; ZBC-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) optsize {
|
||||
; NOZBC-LABEL: define i32 @crc32.le.tc8.data32(
|
||||
; NOZBC-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; NOZBC-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; 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: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; ZBC32-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; ZBC32-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; ZBC32-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; ZBC32-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; ZBC32-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; ZBC32-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; ZBC32-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; ZBC32-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; ZBC32-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC32: [[EXIT]]:
|
||||
; ZBC32-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC64-LABEL: define i32 @crc32.le.tc8.data32(
|
||||
; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; ZBC64-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC64-NEXT: [[CRC_CAST:%.*]] = zext i32 [[CHECKSUM]] to i40
|
||||
; ZBC64-NEXT: [[DATA_CAST:%.*]] = zext i32 [[MSG]] to i40
|
||||
; ZBC64-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC64-NEXT: [[CRC_TCBITS:%.*]] = and i40 [[XOR_CRC_DATA1]], 255
|
||||
; ZBC64-NEXT: [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[CRC_TCBITS]], i40 273)
|
||||
; ZBC64-NEXT: [[QUOT_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
|
||||
; ZBC64-NEXT: [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_MASK]], i40 67601)
|
||||
; ZBC64-NEXT: [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; ZBC64-NEXT: [[CRC_LSHR2:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
|
||||
; ZBC64-NEXT: [[CRC_NEXT3:%.*]] = trunc i40 [[CRC_LSHR2]] to i32
|
||||
; ZBC64-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC64: [[LOOP]]:
|
||||
; ZBC64-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC64: [[EXIT]]:
|
||||
; ZBC64-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[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 i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) optsize {
|
||||
; NOZBC-LABEL: define i8 @crc8.le.tc8.data32(
|
||||
; NOZBC-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA_TRUNC:%.*]] = trunc i32 [[DATA]] to i8
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOZBC-NEXT: [[SB_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[SB_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 59
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC-LABEL: define i8 @crc8.le.tc8.data32(
|
||||
; ZBC-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; ZBC-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i16
|
||||
; ZBC-NEXT: [[DATA_CAST:%.*]] = trunc i32 [[MSG]] to i16
|
||||
; ZBC-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC-NEXT: [[CRC_TCBITS:%.*]] = and i16 [[XOR_CRC_DATA1]], 255
|
||||
; ZBC-NEXT: [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_TCBITS]], i16 107)
|
||||
; ZBC-NEXT: [[QUOT_MASK:%.*]] = and i16 [[CLMUL_MU]], 255
|
||||
; ZBC-NEXT: [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_MASK]], i16 119)
|
||||
; ZBC-NEXT: [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; ZBC-NEXT: [[CRC_LSHR2:%.*]] = lshr i16 [[XOR_CRC_MULT]], 8
|
||||
; ZBC-NEXT: [[CRC_NEXT3:%.*]] = trunc i16 [[CRC_LSHR2]] to i8
|
||||
; ZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC: [[LOOP]]:
|
||||
; ZBC-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC: [[EXIT]]:
|
||||
; ZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; ZBC-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%data.trunc = trunc i32 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%sb.crc.data = and i8 %xor.crc.data, 1
|
||||
%check.sb = icmp eq i8 %sb.crc.data, 0
|
||||
%crc.lshr = lshr i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.lshr, 59
|
||||
%crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%data.next = lshr i32 %data, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i32 @crc32.le.tc32(i32 %checksum, i32 %msg) optsize {
|
||||
; NOZBC-LABEL: define i32 @crc32.le.tc32(
|
||||
; NOZBC-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; NOZBC-NEXT: [[ENTRY:.*]]:
|
||||
; NOZBC-NEXT: br label %[[LOOP:.*]]
|
||||
; NOZBC: [[LOOP]]:
|
||||
; NOZBC-NEXT: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; NOZBC-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; NOZBC-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; NOZBC-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; NOZBC-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; NOZBC-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; NOZBC-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOZBC-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOZBC-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 31
|
||||
; NOZBC-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOZBC: [[EXIT]]:
|
||||
; NOZBC-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOZBC-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC32-LABEL: define i32 @crc32.le.tc32(
|
||||
; ZBC32-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; ZBC32-NEXT: [[ENTRY:.*]]:
|
||||
; ZBC32-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC32: [[LOOP]]:
|
||||
; ZBC32-NEXT: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; ZBC32-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; ZBC32-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; ZBC32-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; ZBC32-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; ZBC32-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; ZBC32-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; ZBC32-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; ZBC32-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 31
|
||||
; ZBC32-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC32: [[EXIT]]:
|
||||
; ZBC32-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; ZBC32-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; ZBC64-LABEL: define i32 @crc32.le.tc32(
|
||||
; ZBC64-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; ZBC64-NEXT: [[ENTRY:.*:]]
|
||||
; ZBC64-NEXT: [[CRC_CAST:%.*]] = zext i32 [[CHECKSUM]] to i64
|
||||
; ZBC64-NEXT: [[DATA_CAST:%.*]] = zext i32 [[MSG]] to i64
|
||||
; ZBC64-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; ZBC64-NEXT: [[CRC_TCBITS:%.*]] = and i64 [[XOR_CRC_DATA1]], 4294967295
|
||||
; ZBC64-NEXT: [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[CRC_TCBITS]], i64 4770502929)
|
||||
; ZBC64-NEXT: [[QUOT_MASK:%.*]] = and i64 [[CLMUL_MU]], 4294967295
|
||||
; ZBC64-NEXT: [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_MASK]], i64 67601)
|
||||
; ZBC64-NEXT: [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; ZBC64-NEXT: [[CRC_LSHR2:%.*]] = lshr i64 [[XOR_CRC_MULT]], 32
|
||||
; ZBC64-NEXT: [[CRC_NEXT3:%.*]] = trunc i64 [[CRC_LSHR2]] to i32
|
||||
; ZBC64-NEXT: br label %[[LOOP:.*]]
|
||||
; ZBC64: [[LOOP]]:
|
||||
; ZBC64-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ZBC64: [[EXIT]]:
|
||||
; ZBC64-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[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, 31
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i32 %crc.next
|
||||
}
|
||||
|
||||
define i64 @crc64.le.tc64(i64 %checksum, i64 %msg) optsize {
|
||||
; ALL-LABEL: define i64 @crc64.le.tc64(
|
||||
; ALL-SAME: i64 [[CHECKSUM:%.*]], i64 [[MSG:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; ALL-NEXT: [[ENTRY:.*]]:
|
||||
; ALL-NEXT: br label %[[LOOP:.*]]
|
||||
; ALL: [[LOOP]]:
|
||||
; ALL-NEXT: [[CRC:%.*]] = phi i64 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[DATA:%.*]] = phi i64 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i64 [[CRC]], [[DATA]]
|
||||
; ALL-NEXT: [[SB_CRC_DATA:%.*]] = and i64 [[XOR_CRC_DATA]], 1
|
||||
; ALL-NEXT: [[CHECK_SB:%.*]] = icmp eq i64 [[SB_CRC_DATA]], 0
|
||||
; ALL-NEXT: [[CRC_LSHR:%.*]] = lshr i64 [[CRC]], 1
|
||||
; ALL-NEXT: [[CRC_XOR:%.*]] = xor i64 [[CRC_LSHR]], 33800
|
||||
; ALL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i64 [[CRC_LSHR]], i64 [[CRC_XOR]]
|
||||
; ALL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; ALL-NEXT: [[DATA_NEXT]] = lshr i64 [[DATA]], 1
|
||||
; ALL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 63
|
||||
; ALL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ALL: [[EXIT]]:
|
||||
; ALL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i64 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; ALL-NEXT: ret i64 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%crc = phi i64 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i64 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%xor.crc.data = xor i64 %crc, %data
|
||||
%sb.crc.data = and i64 %xor.crc.data, 1
|
||||
%check.sb = icmp eq i64 %sb.crc.data, 0
|
||||
%crc.lshr = lshr i64 %crc, 1
|
||||
%crc.xor = xor i64 %crc.lshr, 33800
|
||||
%crc.next = select i1 %check.sb, i64 %crc.lshr, i64 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%data.next = lshr i64 %data, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 63
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i64 %crc.next
|
||||
}
|
||||
;.
|
||||
; NOZBC32: attributes #[[ATTR0]] = { optsize "target-features"="-zbc" }
|
||||
;.
|
||||
; NOZBC64: attributes #[[ATTR0]] = { optsize "target-features"="-zbc" }
|
||||
;.
|
||||
; ZBC32: attributes #[[ATTR0]] = { optsize "target-features"="+zbc" }
|
||||
; ZBC32: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
;.
|
||||
; ZBC64: attributes #[[ATTR0]] = { optsize "target-features"="+zbc" }
|
||||
; ZBC64: attributes #[[ATTR1:[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:
|
||||
; NOZBC32: {{.*}}
|
||||
; NOZBC64: {{.*}}
|
||||
707
llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
Normal file
707
llvm/test/Transforms/LoopIdiom/X86/cyclic-redundancy-check.ll
Normal file
|
|
@ -0,0 +1,707 @@
|
|||
; 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
|
||||
|
||||
define i16 @crc16.le.tc8(i8 %msg, i16 %checksum) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
|
||||
; NOPCLMUL-NEXT: [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
|
||||
; NOPCLMUL-NEXT: [[AND_DATA_CRC:%.*]] = and i8 [[XOR_DATA_CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = lshr i8 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[AND_DATA_CRC]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[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: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i24
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = zext i8 [[MSG]] to i24
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i24 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i24 [[XOR_CRC_DATA]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_TCBITS]], i24 511)
|
||||
; PCLMUL-NEXT: [[QUOT_MASK:%.*]] = and i24 [[CLMUL_MU]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_MASK]], i24 81923)
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_LSHR1:%.*]] = lshr i24 [[XOR_CRC_MULT]], 8
|
||||
; PCLMUL-NEXT: [[CRC_NEXT2:%.*]] = trunc i24 [[CRC_LSHR1]] to i16
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
|
||||
; PCLMUL-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
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.tc16(i16 %msg, i16 %checksum) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
|
||||
; NOPCLMUL-NEXT: [[AND_CRC_DATA:%.*]] = and i16 [[XOR_CRC_DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = lshr i16 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp eq i16 [[AND_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_LSHR:%.*]] = lshr i16 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i16 [[CRC_LSHR]], -24575
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_LSHR]], i16 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[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: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i32
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 114687)
|
||||
; PCLMUL-NEXT: [[QUOT_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_MASK]], i32 81923)
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_LSHR2:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[CRC_LSHR2]] to i16
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[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) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOPCLMUL-NEXT: [[AND_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = lshr i16 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[AND_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 29
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[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: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i32
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 24423)
|
||||
; PCLMUL-NEXT: [[QUOT_MASK:%.*]] = and i32 [[CLMUL_MU]], 65535
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_MASK]], i32 59)
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_LSHR2:%.*]] = lshr i32 [[XOR_CRC_MULT]], 16
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[CRC_LSHR2]] to i8
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; PCLMUL-NEXT: 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.tc16(i16 %msg, i16 %checksum) optsize {
|
||||
; NOPCLMUL-LABEL: define i16 @crc16.be.tc16(
|
||||
; NOPCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOPCLMUL-NEXT: [[ENTRY:.*]]:
|
||||
; NOPCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; NOPCLMUL: [[LOOP]]:
|
||||
; NOPCLMUL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i16 [[CRC]], [[DATA]]
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp sge i16 [[XOR_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; PCLMUL-LABEL: define i16 @crc16.be.tc16(
|
||||
; PCLMUL-SAME: i16 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; PCLMUL-NEXT: [[ENTRY:.*:]]
|
||||
; PCLMUL-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i32
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[XOR_CRC_DATA1]], 65535
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 69936)
|
||||
; PCLMUL-NEXT: [[QUOT_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LSHR]], i32 69665)
|
||||
; PCLMUL-NEXT: [[CRC_SHL2:%.*]] = shl i32 [[CRC_CAST]], 16
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i16
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; PCLMUL-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%xor.crc.data = xor i16 %crc, %data
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i16 %xor.crc.data, 0
|
||||
%crc.shl = shl i16 %crc, 1
|
||||
%crc.xor = xor i16 %crc.shl, 4129
|
||||
%crc.next = select i1 %check.sb, i16 %crc.shl, i16 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i16 @crc16.be.tc8.misalign(i8 %msg, i16 %checksum) optsize {
|
||||
; NOPCLMUL-LABEL: define i16 @crc16.be.tc8.misalign(
|
||||
; NOPCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOPCLMUL-NEXT: [[ENTRY:.*]]:
|
||||
; NOPCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; NOPCLMUL: [[LOOP]]:
|
||||
; NOPCLMUL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[CRC:%.*]] = phi i16 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i8 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[CRC_TRUNC:%.*]] = trunc i16 [[CRC]] to i8
|
||||
; NOPCLMUL-NEXT: [[XOR_DATA_CRC:%.*]] = xor i8 [[DATA]], [[CRC_TRUNC]]
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = shl i8 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_DATA_CRC]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_SHL:%.*]] = shl i16 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[XOR:%.*]] = xor i16 [[CRC_SHL]], 4129
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i16 [[CRC_SHL]], i16 [[XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; PCLMUL-LABEL: define i16 @crc16.be.tc8.misalign(
|
||||
; PCLMUL-SAME: i8 [[MSG:%.*]], i16 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; PCLMUL-NEXT: [[ENTRY:.*:]]
|
||||
; PCLMUL-NEXT: [[CRC_CAST:%.*]] = zext i16 [[CHECKSUM]] to i24
|
||||
; PCLMUL-NEXT: [[CRC_ALIGN_TC:%.*]] = lshr i24 [[CRC_CAST]], 8
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i24 [[CRC_ALIGN_TC]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i24 @llvm.clmul.i24(i24 [[CRC_TCBITS]], i24 273)
|
||||
; PCLMUL-NEXT: [[QUOT_LSHR:%.*]] = lshr i24 [[CLMUL_MU]], 8
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i24 @llvm.clmul.i24(i24 [[QUOT_LSHR]], i24 69665)
|
||||
; PCLMUL-NEXT: [[CRC_SHL1:%.*]] = shl i24 [[CRC_CAST]], 8
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i24 [[CRC_SHL1]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_NEXT2:%.*]] = trunc i24 [[XOR_CRC_MULT]] to i16
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i16 [ [[CRC_NEXT2]], %[[LOOP]] ]
|
||||
; PCLMUL-NEXT: ret i16 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i16 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i8 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%crc.trunc = trunc i16 %crc to i8
|
||||
%xor.data.crc = xor i8 %data, %crc.trunc
|
||||
%data.next = shl i8 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.data.crc, 0
|
||||
%crc.shl = shl i16 %crc, 1
|
||||
%xor = xor i16 %crc.shl, 4129
|
||||
%crc.next = select i1 %check.sb, i16 %crc.shl, i16 %xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i16 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc16.misalign(i16 %msg, i8 %checksum) optsize {
|
||||
; NOPCLMUL-LABEL: define i8 @crc8.be.tc16.misalign(
|
||||
; NOPCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOPCLMUL-NEXT: [[ENTRY:.*]]:
|
||||
; NOPCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; NOPCLMUL: [[LOOP]]:
|
||||
; NOPCLMUL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_SHL]], i8 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 15
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; PCLMUL-LABEL: define i8 @crc8.be.tc16.misalign(
|
||||
; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; PCLMUL-NEXT: [[ENTRY:.*:]]
|
||||
; PCLMUL-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i32
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = zext i16 [[MSG]] to i32
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i32 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_ALIGN_TC:%.*]] = shl i32 [[XOR_CRC_DATA1]], 8
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i32 [[CRC_ALIGN_TC]], 65535
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i32 @llvm.clmul.i32(i32 [[CRC_TCBITS]], i32 72779)
|
||||
; PCLMUL-NEXT: [[QUOT_LSHR:%.*]] = lshr i32 [[CLMUL_MU]], 16
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i32 @llvm.clmul.i32(i32 [[QUOT_LSHR]], i32 285)
|
||||
; PCLMUL-NEXT: [[CRC_SHL2:%.*]] = shl i32 [[CRC_CAST]], 16
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i32 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i32 [[XOR_CRC_MULT]] to i8
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; PCLMUL-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 15
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i8 @crc8.be.tc8.data16.misalign(i16 %msg, i8 %checksum) optsize {
|
||||
; NOPCLMUL-LABEL: define i8 @crc8.be.tc8.data16.misalign(
|
||||
; NOPCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; NOPCLMUL-NEXT: [[ENTRY:.*]]:
|
||||
; NOPCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; NOPCLMUL: [[LOOP]]:
|
||||
; NOPCLMUL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i16 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA_TRUNC:%.*]] = trunc i16 [[DATA]] to i8
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = shl i16 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp sge i8 [[XOR_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_SHL:%.*]] = shl i8 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_SHL]], 29
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_SHL]], i8 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; PCLMUL-LABEL: define i8 @crc8.be.tc8.data16.misalign(
|
||||
; PCLMUL-SAME: i16 [[MSG:%.*]], i8 [[CHECKSUM:%.*]]) #[[ATTR0]] {
|
||||
; PCLMUL-NEXT: [[ENTRY:.*:]]
|
||||
; PCLMUL-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i16
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_CAST]], [[MSG]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i16 [[XOR_CRC_DATA1]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_TCBITS]], i16 284)
|
||||
; PCLMUL-NEXT: [[QUOT_LSHR:%.*]] = lshr i16 [[CLMUL_MU]], 8
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_LSHR]], i16 285)
|
||||
; PCLMUL-NEXT: [[CRC_SHL2:%.*]] = shl i16 [[CRC_CAST]], 8
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_SHL2]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i16 [[XOR_CRC_MULT]] to i8
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; PCLMUL-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i16 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%data.trunc = trunc i16 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%data.next = shl i16 %data, 1
|
||||
%check.sb = icmp sge i8 %xor.crc.data, 0
|
||||
%crc.shl = shl i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.shl, 29
|
||||
%crc.next = select i1 %check.sb, i8 %crc.shl, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i32 @crc32.le.tc8.data32(i32 %checksum, i32 %msg) optsize {
|
||||
; 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: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; NOPCLMUL-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; PCLMUL-LABEL: define i32 @crc32.le.tc8.data32(
|
||||
; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; PCLMUL-NEXT: [[ENTRY:.*:]]
|
||||
; PCLMUL-NEXT: [[CRC_CAST:%.*]] = zext i32 [[CHECKSUM]] to i40
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = zext i32 [[MSG]] to i40
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i40 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i40 [[XOR_CRC_DATA1]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i40 @llvm.clmul.i40(i40 [[CRC_TCBITS]], i40 273)
|
||||
; PCLMUL-NEXT: [[QUOT_MASK:%.*]] = and i40 [[CLMUL_MU]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i40 @llvm.clmul.i40(i40 [[QUOT_MASK]], i40 67601)
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i40 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_LSHR2:%.*]] = lshr i40 [[XOR_CRC_MULT]], 8
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i40 [[CRC_LSHR2]] to i32
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[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 i8 @crc8.le.tc8.data32(i8 %checksum, i32 %msg) optsize {
|
||||
; NOPCLMUL-LABEL: define i8 @crc8.le.tc8.data32(
|
||||
; NOPCLMUL-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; NOPCLMUL-NEXT: [[ENTRY:.*]]:
|
||||
; NOPCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; NOPCLMUL: [[LOOP]]:
|
||||
; NOPCLMUL-NEXT: [[CRC:%.*]] = phi i8 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA_TRUNC:%.*]] = trunc i32 [[DATA]] to i8
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i8 [[CRC]], [[DATA_TRUNC]]
|
||||
; NOPCLMUL-NEXT: [[SB_CRC_DATA:%.*]] = and i8 [[XOR_CRC_DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp eq i8 [[SB_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_LSHR:%.*]] = lshr i8 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i8 [[CRC_LSHR]], 59
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i8 [[CRC_LSHR]], i8 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 7
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; PCLMUL-LABEL: define i8 @crc8.le.tc8.data32(
|
||||
; PCLMUL-SAME: i8 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; PCLMUL-NEXT: [[ENTRY:.*:]]
|
||||
; PCLMUL-NEXT: [[CRC_CAST:%.*]] = zext i8 [[CHECKSUM]] to i16
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = trunc i32 [[MSG]] to i16
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i16 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i16 [[XOR_CRC_DATA1]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i16 @llvm.clmul.i16(i16 [[CRC_TCBITS]], i16 107)
|
||||
; PCLMUL-NEXT: [[QUOT_MASK:%.*]] = and i16 [[CLMUL_MU]], 255
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i16 @llvm.clmul.i16(i16 [[QUOT_MASK]], i16 119)
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i16 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_LSHR2:%.*]] = lshr i16 [[XOR_CRC_MULT]], 8
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i16 [[CRC_LSHR2]] to i8
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i8 [ [[CRC_NEXT3]], %[[LOOP]] ]
|
||||
; PCLMUL-NEXT: ret i8 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%crc = phi i8 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%data.trunc = trunc i32 %data to i8
|
||||
%xor.crc.data = xor i8 %crc, %data.trunc
|
||||
%sb.crc.data = and i8 %xor.crc.data, 1
|
||||
%check.sb = icmp eq i8 %sb.crc.data, 0
|
||||
%crc.lshr = lshr i8 %crc, 1
|
||||
%crc.xor = xor i8 %crc.lshr, 59
|
||||
%crc.next = select i1 %check.sb, i8 %crc.lshr, i8 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%data.next = lshr i32 %data, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 7
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i8 %crc.next
|
||||
}
|
||||
|
||||
define i32 @crc32.le.tc32(i32 %checksum, i32 %msg) optsize {
|
||||
; NOPCLMUL-LABEL: define i32 @crc32.le.tc32(
|
||||
; NOPCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; NOPCLMUL-NEXT: [[ENTRY:.*]]:
|
||||
; NOPCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; NOPCLMUL: [[LOOP]]:
|
||||
; NOPCLMUL-NEXT: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
|
||||
; NOPCLMUL-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
|
||||
; NOPCLMUL-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
|
||||
; NOPCLMUL-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
|
||||
; NOPCLMUL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; NOPCLMUL-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
|
||||
; NOPCLMUL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 31
|
||||
; NOPCLMUL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; NOPCLMUL: [[EXIT]]:
|
||||
; NOPCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; NOPCLMUL-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
; PCLMUL-LABEL: define i32 @crc32.le.tc32(
|
||||
; PCLMUL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR0]] {
|
||||
; PCLMUL-NEXT: [[ENTRY:.*:]]
|
||||
; PCLMUL-NEXT: [[CRC_CAST:%.*]] = zext i32 [[CHECKSUM]] to i64
|
||||
; PCLMUL-NEXT: [[DATA_CAST:%.*]] = zext i32 [[MSG]] to i64
|
||||
; PCLMUL-NEXT: [[XOR_CRC_DATA1:%.*]] = xor i64 [[CRC_CAST]], [[DATA_CAST]]
|
||||
; PCLMUL-NEXT: [[CRC_TCBITS:%.*]] = and i64 [[XOR_CRC_DATA1]], 4294967295
|
||||
; PCLMUL-NEXT: [[CLMUL_MU:%.*]] = call i64 @llvm.clmul.i64(i64 [[CRC_TCBITS]], i64 4770502929)
|
||||
; PCLMUL-NEXT: [[QUOT_MASK:%.*]] = and i64 [[CLMUL_MU]], 4294967295
|
||||
; PCLMUL-NEXT: [[CLMUL_GP:%.*]] = call i64 @llvm.clmul.i64(i64 [[QUOT_MASK]], i64 67601)
|
||||
; PCLMUL-NEXT: [[XOR_CRC_MULT:%.*]] = xor i64 [[CRC_CAST]], [[CLMUL_GP]]
|
||||
; PCLMUL-NEXT: [[CRC_LSHR2:%.*]] = lshr i64 [[XOR_CRC_MULT]], 32
|
||||
; PCLMUL-NEXT: [[CRC_NEXT3:%.*]] = trunc i64 [[CRC_LSHR2]] to i32
|
||||
; PCLMUL-NEXT: br label %[[LOOP:.*]]
|
||||
; PCLMUL: [[LOOP]]:
|
||||
; PCLMUL-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; PCLMUL: [[EXIT]]:
|
||||
; PCLMUL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT3]], %[[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, 31
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i32 %crc.next
|
||||
}
|
||||
|
||||
define i64 @crc64.le.tc64(i64 %checksum, i64 %msg) optsize {
|
||||
; ALL-LABEL: define i64 @crc64.le.tc64(
|
||||
; ALL-SAME: i64 [[CHECKSUM:%.*]], i64 [[MSG:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; ALL-NEXT: [[ENTRY:.*]]:
|
||||
; ALL-NEXT: br label %[[LOOP:.*]]
|
||||
; ALL: [[LOOP]]:
|
||||
; ALL-NEXT: [[CRC:%.*]] = phi i64 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[DATA:%.*]] = phi i64 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
|
||||
; ALL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i64 [[CRC]], [[DATA]]
|
||||
; ALL-NEXT: [[SB_CRC_DATA:%.*]] = and i64 [[XOR_CRC_DATA]], 1
|
||||
; ALL-NEXT: [[CHECK_SB:%.*]] = icmp eq i64 [[SB_CRC_DATA]], 0
|
||||
; ALL-NEXT: [[CRC_LSHR:%.*]] = lshr i64 [[CRC]], 1
|
||||
; ALL-NEXT: [[CRC_XOR:%.*]] = xor i64 [[CRC_LSHR]], 33800
|
||||
; ALL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i64 [[CRC_LSHR]], i64 [[CRC_XOR]]
|
||||
; ALL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
|
||||
; ALL-NEXT: [[DATA_NEXT]] = lshr i64 [[DATA]], 1
|
||||
; ALL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 63
|
||||
; ALL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
|
||||
; ALL: [[EXIT]]:
|
||||
; ALL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i64 [ [[CRC_NEXT]], %[[LOOP]] ]
|
||||
; ALL-NEXT: ret i64 [[CRC_NEXT_LCSSA]]
|
||||
;
|
||||
entry:
|
||||
br label %loop
|
||||
|
||||
loop: ; preds = %loop, %entry
|
||||
%crc = phi i64 [ %checksum, %entry ], [ %crc.next, %loop ]
|
||||
%data = phi i64 [ %msg, %entry ], [ %data.next, %loop ]
|
||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||
%xor.crc.data = xor i64 %crc, %data
|
||||
%sb.crc.data = and i64 %xor.crc.data, 1
|
||||
%check.sb = icmp eq i64 %sb.crc.data, 0
|
||||
%crc.lshr = lshr i64 %crc, 1
|
||||
%crc.xor = xor i64 %crc.lshr, 33800
|
||||
%crc.next = select i1 %check.sb, i64 %crc.lshr, i64 %crc.xor
|
||||
%iv.next = add nuw nsw i8 %iv, 1
|
||||
%data.next = lshr i64 %data, 1
|
||||
%exit.cond = icmp samesign ult i8 %iv, 63
|
||||
br i1 %exit.cond, label %loop, label %exit
|
||||
|
||||
exit: ; preds = %loop
|
||||
ret i64 %crc.next
|
||||
}
|
||||
;.
|
||||
; NOPCLMUL: attributes #[[ATTR0]] = { optsize "target-features"="-pclmul" }
|
||||
;.
|
||||
; PCLMUL: attributes #[[ATTR0]] = { optsize "target-features"="+pclmul" }
|
||||
; PCLMUL: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
;.
|
||||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue