[llvm] [LoopIdiom] Use costing to determine CRC strategy (PR #211040)
Sean Clarke via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 28 11:54:17 PDT 2026
================
@@ -744,17 +1153,65 @@ loop: ; preds = %loop, %entry
exit: ; preds = %loop
ret i64 %crc.next
}
+
+define i32 @crc.disabled.optsize(i32 %checksum, i32 %msg) optsize {
+; ALL-LABEL: define i32 @crc.disabled.optsize(
+; ALL-SAME: i32 [[CHECKSUM:%.*]], i32 [[MSG:%.*]]) #[[ATTR1:[0-9]+]] {
+; ALL-NEXT: [[ENTRY:.*]]:
+; ALL-NEXT: br label %[[LOOP:.*]]
+; ALL: [[LOOP]]:
+; ALL-NEXT: [[CRC:%.*]] = phi i32 [ [[CHECKSUM]], %[[ENTRY]] ], [ [[CRC_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT: [[DATA:%.*]] = phi i32 [ [[MSG]], %[[ENTRY]] ], [ [[DATA_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
+; ALL-NEXT: [[XOR_CRC_DATA:%.*]] = xor i32 [[CRC]], [[DATA]]
+; ALL-NEXT: [[SB_CRC_DATA:%.*]] = and i32 [[XOR_CRC_DATA]], 1
+; ALL-NEXT: [[CHECK_SB:%.*]] = icmp eq i32 [[SB_CRC_DATA]], 0
+; ALL-NEXT: [[CRC_LSHR:%.*]] = lshr i32 [[CRC]], 1
+; ALL-NEXT: [[CRC_XOR:%.*]] = xor i32 [[CRC_LSHR]], 33800
+; ALL-NEXT: [[CRC_NEXT]] = select i1 [[CHECK_SB]], i32 [[CRC_LSHR]], i32 [[CRC_XOR]]
+; ALL-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
+; ALL-NEXT: [[DATA_NEXT]] = lshr i32 [[DATA]], 1
+; ALL-NEXT: [[EXIT_COND:%.*]] = icmp samesign ult i8 [[IV]], 31
+; ALL-NEXT: br i1 [[EXIT_COND]], label %[[LOOP]], label %[[EXIT:.*]]
+; ALL: [[EXIT]]:
+; ALL-NEXT: [[CRC_NEXT_LCSSA:%.*]] = phi i32 [ [[CRC_NEXT]], %[[LOOP]] ]
+; ALL-NEXT: ret i32 [[CRC_NEXT_LCSSA]]
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %crc = phi i32 [ %checksum, %entry ], [ %crc.next, %loop ]
+ %data = phi i32 [ %msg, %entry ], [ %data.next, %loop ]
+ %iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
+ %xor.crc.data = xor i32 %crc, %data
+ %sb.crc.data = and i32 %xor.crc.data, 1
+ %check.sb = icmp eq i32 %sb.crc.data, 0
+ %crc.lshr = lshr i32 %crc, 1
+ %crc.xor = xor i32 %crc.lshr, 33800
+ %crc.next = select i1 %check.sb, i32 %crc.lshr, i32 %crc.xor
+ %iv.next = add nuw nsw i8 %iv, 1
+ %data.next = lshr i32 %data, 1
+ %exit.cond = icmp samesign ult i8 %iv, 31
+ br i1 %exit.cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret i32 %crc.next
+}
;.
-; NOZBC32: attributes #[[ATTR0]] = { optsize "target-features"="-zbc" }
+; NOZBC32: attributes #[[ATTR0]] = { "target-features"="-zbc" }
+; NOZBC32: attributes #[[ATTR1]] = { optsize "target-features"="-zbc" }
;.
-; NOZBC64: attributes #[[ATTR0]] = { optsize "target-features"="-zbc" }
+; NOZBC64: attributes #[[ATTR0]] = { "target-features"="-zbc" }
+; NOZBC64: attributes #[[ATTR1]] = { 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) }
+; ZBC32: attributes #[[ATTR0]] = { "target-features"="+zbc" }
+; ZBC32: attributes #[[ATTR1]] = { optsize "target-features"="+zbc" }
+; ZBC32: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
;.
-; ZBC64: attributes #[[ATTR0]] = { optsize "target-features"="+zbc" }
-; ZBC64: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+; ZBC64: attributes #[[ATTR0]] = { "target-features"="+zbc" }
+; ZBC64: attributes #[[ATTR1]] = { optsize "target-features"="+zbc" }
+; ZBC64: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
;.
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; NOZBC32: {{.*}}
-; NOZBC64: {{.*}}
+; NOZBC: {{.*}}
----------------
xarkenz wrote:
Removing `NOZBC` would make the `RUN` lines weirdly asymmetrical. If that's fine, though, I can do that.
https://github.com/llvm/llvm-project/pull/211040
More information about the llvm-commits
mailing list