[clang] [CIR] Rewrite a raised std::find over bytes into memchr (PR #212355)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 28 06:19:34 PDT 2026


================
@@ -50,26 +51,95 @@ struct LibOptPass : public impl::LibOptBase<LibOptPass> {
   // Raw libopt option string forwarded by the frontend. This will later control
   // which optimizations the pass enables.
   std::string optimizationOptions;
-
-  /// Tracks current module.
-  ModuleOp theModule;
 };
 } // namespace
 
 mlir::LogicalResult LibOptPass::initializeOptions(
     llvm::StringRef options,
-    llvm::function_ref<mlir::LogicalResult(const llvm::Twine &)> errorHandler) {
-  (void)errorHandler;
+    llvm::function_ref<mlir::LogicalResult(const llvm::Twine &)>) {
   optimizationOptions = options.str();
   // TODO(cir): Parse options to select the active transformations for the
   // pass.
   return mlir::success();
 }
 
+static void rewriteStdFindToMemchr(StdFindOp findOp,
+                                   mlir::SymbolTableCollection &symbolTables) {
+  auto iterTy = mlir::dyn_cast<cir::PointerType>(findOp.getResult().getType());
+  if (!iterTy || iterTy.getAddrSpace())
+    return;
+  auto elemTy = mlir::dyn_cast<cir::IntType>(iterTy.getPointee());
+  if (!elemTy || elemTy.getWidth() != 8)
+    return;
+
+  auto patternPtrTy =
+      mlir::dyn_cast<cir::PointerType>(findOp.getPattern().getType());
+  if (!patternPtrTy || patternPtrTy.getPointee() != elemTy)
+    return;
+
+  // No builtin state rides on both the raised call and the enclosing function.
+  auto enclosing = findOp->getParentOfType<cir::FuncOp>();
+  if (isNoBuiltin(findOp, "memchr") ||
+      (enclosing && noBuiltinsForbid(enclosing, "memchr"))) {
+    return;
+  }
+
+  // An enum or atomic element also lowers to a byte wide integer.
+  auto callee = symbolTables.lookupNearestSymbolFrom<cir::FuncOp>(
+      findOp, findOp.getOriginalFnAttr());
+  auto funcIdentity = mlir::dyn_cast_if_present<cir::FuncIdentityAttr>(
+      callee ? callee.getFuncInfoAttr() : mlir::Attribute());
+  if (!funcIdentity || funcIdentity.getKind() != cir::KnownFuncKind::StdFind ||
+      !funcIdentity.getNarrowCharParams()) {
+    return;
+  }
+
+  // cir.libc.memchr fixes the value and length widths at 32 and 64 bits.
+  // TODO(cir): gate on the target size type and libcall availability.
+  auto moduleOp = findOp->getParentOfType<mlir::ModuleOp>();
+  auto tripleAttr = moduleOp ? moduleOp->getAttrOfType<mlir::StringAttr>(
+                                   cir::CIRDialect::getTripleAttrName())
+                             : nullptr;
+  if (!tripleAttr)
+    return;
+  llvm::Triple triple(tripleAttr.getValue().str());
+
+  bool sizeTypeMismatch = !triple.isArch64Bit() || triple.isX32() ||
----------------
erichkeane wrote:

give me a comment on these two as well, it isn't clear what is going on with either of them still.  The names help however.

https://github.com/llvm/llvm-project/pull/212355


More information about the cfe-commits mailing list