[llvm] [LoopIdiom] Use costing to determine CRC strategy (PR #211040)
Sean Clarke via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 22 08:00:06 PDT 2026
================
@@ -1589,43 +1600,113 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
if (TT.getArch() == Triple::hexagon)
return false;
- // The force-crc-clmul flag should cause the clmul optimization to run
- // unconditionally.
- if (ForceCRCClmul) {
+ // The Sarwate lookup table optimization requires a byte-multiple trip count,
+ // and should not be applied if optimizing for size.
+ bool TableStrategyPossible =
+ Info.TripCount % 8 == 0 && !ApplyCodeSizeHeuristics;
+
+ switch (CRCStrategy) {
+ default:
+ break;
+ case CRCStrategyKind::Table: {
+ if (TableStrategyPossible) {
+ optimizeCRCLoopUsingTableLookup(Info);
+ return true;
+ }
+ return false;
+ }
+ case CRCStrategyKind::Clmul:
optimizeCRCLoopUsingClmul(Info);
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 && Info.TripCount % 8 == 0) {
- optimizeCRCLoopUsingTableLookup(Info);
+ LLVMContext &Ctx = Info.LHS->getContext();
+ Type *CRCTy = Info.LHS->getType();
+ unsigned CRCBW = CRCTy->getIntegerBitWidth();
+
+ // The clmul optimization should be applied on optsize if clmul with the
+ // required bit width is a fast operation on the target. The first clmul needs
+ // 2*TC bits, and the second clmul needs CRCBW+TC bits, so test the wider one.
+ // FIXME: I'm not sure it makes sense to have this anymore. Optsize might need
+ // separate costing to determine which is smaller.
+ IntegerType *WidestClmulTy = IntegerType::get(
+ Ctx, std::max(2 * Info.TripCount, CRCBW + Info.TripCount));
+ if (ApplyCodeSizeHeuristics && TTI->haveFastClmul(WidestClmulTy)) {
+ optimizeCRCLoopUsingClmul(Info);
return true;
}
- // The clmul optimization should only be applied if clmul with the required
- // bit width is a fast operation on the target. The first clmul needs 2*TC
- // bits, and the second clmul needs CRCBW+TC bits, so test the widest clmul.
- // TODO: If clmul exists on the target but not for the required width, it
- // might be possible to split into multiple iterations of reduction.
- unsigned CRCBW = Info.LHS->getType()->getIntegerBitWidth();
- IntegerType *WidestClmulTy =
- IntegerType::get(Info.LHS->getContext(),
- std::max(2 * Info.TripCount, CRCBW + Info.TripCount));
- if (TTI->haveFastClmul(WidestClmulTy)) {
+ TargetTransformInfo::TargetCostKind CostKind =
+ TargetTransformInfo::TCK_Latency;
----------------
xarkenz wrote:
My understanding is that generally latency is used for costing of serial code and reciprocal throughput for parallel code. The CRC loop seems very serial, which is why I opted for this. It also gives a much better comparison between the two optimizations in this case, from my testing. I'm open to suggestions if you have a better idea of how to cost this.
https://github.com/llvm/llvm-project/pull/211040
More information about the llvm-commits
mailing list