Consistently query `ExecutableTargetAttr` (#11291)

#11057 added a `IREE::HAL::ExecutableTargetAttr::lookup` function which
should be the preferred way to get a `ExecutableTargetAttr`, since it
honors the overrides made possible by that PR.

It's also neatly shrinking code at call sites, and better conveys
intent: before, we were querying a `ExecutableVariantOp` only to get at
the `ExecutableTargetAttr`, now we query directly the latter.

The Utils are updated to all take a `ExecutableTargetAttr`, and since
they were already implementing logic to handle optionally present
fields, this further simplifies logic at call sites.

Some Utils implementation functions, which were internal, are now
exposed in `Utils.h`. Particularly `getConfigStringAttr`. There seemed
to be no point having various place in the code reimplement that
boilerplate themselves (with opportunities to mishandle optionals). A
new `getConfigIntegerAttr` is added.

This is preparation for determining tile sizes based on target info in
`MaterializeEncoding`, which following #11290 we will be able to do
based on the `ExecutableTargetAttr` which we query there. It would be
inconvenient, at least for testing purposes, to have to deal only with
`ExecutableVariantOp` there, so the new `MaterializeEncoding` code in
#11290 is using `IREE::HAL::ExecutableTargetAttr::lookup` and needs to
access helpers taking a `ExecutableTargetAttr`, which was the original
motivation for the `Utils.*` changes here.
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp
index 0f2feb6..35a975f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp
@@ -1122,16 +1122,9 @@
 
 static std::string getStringAttrFromTargetAttr(ModuleOp module,
                                                StringRef attrName) {
-  if (auto variantOp =
-          module->getParentOfType<IREE::HAL::ExecutableVariantOp>()) {
-    IREE::HAL::ExecutableTargetAttr targetAttr = variantOp.getTarget();
-    if (auto config = targetAttr.getConfiguration()) {
-      if (auto attr = config.getAs<StringAttr>(attrName)) {
-        return attr.getValue().str();
-      }
-    }
-  }
-  return "";
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(module);
+  auto stringAttr = getConfigStringAttr(targetAttr, attrName);
+  return stringAttr ? stringAttr.value().str() : std::string("");
 }
 
 void ConvertToLLVMPass::runOnOperation() {
@@ -1194,13 +1187,13 @@
   //
   // TODO(bjacob): Use a lowering that uses specific ARM/X86 intrinsics.
   bool use32BitImpl = false;
-  auto variantOp = getExecutableVariantOp(module);
-  if (succeeded(variantOp) && isRISCV(*variantOp)) {
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(module);
+  if (isRISCV(targetAttr)) {
     // Use the 32-bit lowering for RISC-V if 'zve32x' is specified and there is
     // no 64-bit integer vector support.
     // TODO(#9440) Simplify logic when 'cpu_features' is simplified.
-    use32BitImpl = hasZve32xFeature(*variantOp) && !hasVFeature(*variantOp) &&
-                   !hasZve64xFeature(*variantOp);
+    use32BitImpl = hasZve32xFeature(targetAttr) && !hasVFeature(targetAttr) &&
+                   !hasZve64xFeature(targetAttr);
   }
   tosa::populateTosaRescaleToArithConversionPatterns(&patterns, use32BitImpl);
 
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp
index 7a529b2..d5d3522 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp
@@ -15,6 +15,7 @@
 #include "iree/compiler/Codegen/Transforms/Transforms.h"
 #include "iree/compiler/Codegen/Utils/Utils.h"
 #include "iree/compiler/Dialect/Flow/IR/FlowOps.h"
+#include "iree/compiler/Dialect/HAL/IR/HALTypes.h"
 #include "llvm/ADT/TypeSwitch.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/TargetSelect.h"
@@ -177,38 +178,31 @@
     return VectorPreProcStrategy::Peeling;
   }
 
-  auto maybeVariantOp = getExecutableVariantOp(linalgOp);
-  assert(succeeded(maybeVariantOp) && "ExecutableVariantOp not found");
-  auto variantOp = *maybeVariantOp;
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(linalgOp);
 
   // Default X86 specific strategy.
-  if (isX86(variantOp) && enableVectorPadding) {
+  if (isX86(targetAttr) && enableVectorPadding) {
     // Padding is only enabled on x86. It leads to too much overhead on RISC-V
     // and ARM.
     return VectorPreProcStrategy::Padding;
   }
 
   // Default RISC-V specific strategies.
-  if (isRISCV(variantOp) && enableVectorPeeling) {
+  if (isRISCV(targetAttr) && enableVectorPeeling) {
     return VectorPreProcStrategy::Peeling;
   }
 
   return VectorPreProcStrategy::None;
 }
 
-/// Looks for the `native_vector_size` attribute in the hal.executable.variant
-/// op.
+/// Looks for the `native_vector_size` attribute in the hal.executable.target
+/// looked up from this op.
 static Optional<int64_t> getNativeVectorSizeInBytes(func::FuncOp entryPointFn) {
-  auto variantOp =
-      entryPointFn->getParentOfType<IREE::HAL::ExecutableVariantOp>();
-  if (!variantOp) return llvm::None;
-  IREE::HAL::ExecutableTargetAttr targetAttr = variantOp.getTarget();
-  if (!targetAttr) return llvm::None;
-  auto config = targetAttr.getConfiguration();
-  if (!config) return llvm::None;
-  auto nativeVectorSizeAttr = config.getAs<IntegerAttr>("native_vector_size");
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
+  auto nativeVectorSizeAttr =
+      getConfigIntegerAttr(targetAttr, "native_vector_size");
   if (!nativeVectorSizeAttr) return llvm::None;
-  int64_t nativeVectorSizeVal = nativeVectorSizeAttr.getInt();
+  int64_t nativeVectorSizeVal = nativeVectorSizeAttr->getInt();
   if (!nativeVectorSizeVal) return llvm::None;
   return nativeVectorSizeVal;
 }
@@ -819,13 +813,13 @@
 static void getDefaultMatmulWorkgroupSizes(linalg::LinalgOp op,
                                            SmallVectorImpl<int64_t> &sizes,
                                            int64_t vectorSize) {
-  auto variantOp = getExecutableVariantOp(op);
-  if (isX86(*variantOp)) {
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(op);
+  if (isX86(targetAttr)) {
     sizes.append({8, 32, 16});
     return;
   }
 
-  if (isRISCV(*variantOp)) {
+  if (isRISCV(targetAttr)) {
     // RISC-V natively supports scalar x vector operations so we don't have to
     // vectorize dimension k. Vectorizing dimension k results in a vector load
     // and a sequence of vrgather ops to implemement the broadcast explicitly.
@@ -846,13 +840,12 @@
                                                     int64_t vectorSize,
                                                     bool isQuantized) {
   SmallVector<int64_t> matmulTileSizes;
-  auto variantOp = getExecutableVariantOp(entryPointFn);
-  assert(succeeded(variantOp) && "ExecutableVariantOp not found");
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
 
   // Compute workgroup tile sizes using heuristics.
-  // TODO: if (isX86(*variantOp) || isRISCV(*variantOp)) {
+  // TODO: if (isX86(targetAttr) || isRISCV(targetAttr)) {
 
-  if (isAArch64(*variantOp)) {
+  if (isAArch64(targetAttr)) {
     if (isQuantized) {
       matmulTileSizes = {vectorSize, vectorSize * 4, vectorSize};
     } else {
@@ -910,12 +903,11 @@
   SmallVector<int64_t> workgroupTileSizes =
       getMatmulWorkgroupSizes(entryPointFn, linalgOp, vectorSize, isQuantized);
 
-  auto variantOp = getExecutableVariantOp(entryPointFn);
-  assert(succeeded(variantOp) && "ExecutableVariantOp not found");
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
 
   // Use the default distribution for the matmul loops.
   int64_t defaultMaxSize = defaultWorkgroupTileSize;
-  if (isX86(*variantOp) || isRISCV(*variantOp)) {
+  if (isX86(targetAttr) || isRISCV(targetAttr)) {
     defaultMaxSize = 128;
   }
 
@@ -959,7 +951,7 @@
   // ARM codgen does not switch to use codegen driver based approach, so we have
   // special logic for it. All the new pipeline is expected to use codegen
   // driver based approach.
-  if (isAArch64(*variantOp) && !isQuantized) {
+  if (isAArch64(targetAttr) && !isQuantized) {
     return setAArch64RootConfig(entryPointFn, contractionOp, flowTileSizes,
                                 workgroupTileSizes, vectorSize);
   }
@@ -1269,9 +1261,8 @@
     return success();
   }
 
-  auto variantOp = getExecutableVariantOp(genericOp);
-  assert(succeeded(variantOp) && "ExecutableVariantOp not found");
-  if (!hasAVX2Feature(*variantOp) || !isSupportedTransposeOp(genericOp)) {
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
+  if (!hasAVX2Feature(targetAttr) || !isSupportedTransposeOp(genericOp)) {
     return success();
   }
 
@@ -1492,24 +1483,23 @@
   assert(isSupported && "conv op is not supported");
 
   SmallVector<int64_t> tileSizes;
-  auto variantOp = getExecutableVariantOp(entryPointFn);
-  assert(succeeded(variantOp) && "ExecutableVariantOp not found");
+  auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
 
-  if (isX86(*variantOp)) {
+  if (isX86(targetAttr)) {
     TypeSwitch<Operation *>(op.getOperation())
         .Case<linalg::Conv2DNhwcHwcfOp>(
             [&](auto op) { tileSizes = {1, 1, 8, vectorSize * 2, 1, 1, 8}; })
         .Case<linalg::DepthwiseConv2DNhwcHwcOp>(
             [&](auto op) { tileSizes = {1, 1, 8, vectorSize * 2, 1, 3}; })
         .Default([&](Operation *op) { llvm_unreachable("unsupported conv"); });
-  } else if (isRISCV(*variantOp)) {
+  } else if (isRISCV(targetAttr)) {
     TypeSwitch<Operation *>(op.getOperation())
         .Case<linalg::Conv2DNhwcHwcfOp>(
             [&](auto op) { tileSizes = {1, 1, 8, vectorSize * 2, 1, 1, 8}; })
         .Case<linalg::DepthwiseConv2DNhwcHwcOp>(
             [&](auto op) { tileSizes = {1, 1, 8, vectorSize, 1, 3}; })
         .Default([&](Operation *op) { llvm_unreachable("unsupported conv"); });
-  } else if (isAArch64(*variantOp)) {
+  } else if (isAArch64(targetAttr)) {
     TypeSwitch<Operation *>(op.getOperation())
         .Case<linalg::Conv2DNhwcHwcfOp>(
             [&](auto op) { tileSizes = {1, 1, 32, 64, 1, 1, 16}; })
@@ -1709,15 +1699,14 @@
   Operation *rootOperation = rootOp.value();
 
   if (rootOperation) {
-    auto variantOp = getExecutableVariantOp(entryPointFn);
-    assert(succeeded(variantOp) && "ExecutableVariantOp not found");
-    if (isVMVXBackend(*variantOp)) {
+    auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
+    if (isVMVXBackend(targetAttr)) {
       if (failed(setVMVXRootConfigImpl(entryPointFn, rootOperation))) {
         return failure();
       }
     } else {
       auto targetMLTransInfo =
-          TargetMLTransformInfo::getTargetMLTransformInfo(*variantOp);
+          TargetMLTransformInfo::getTargetMLTransformInfo(targetAttr);
       if (failed(setRootConfigImpl(entryPointFn, rootOperation,
                                    targetMLTransInfo))) {
         return failure();
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp
index a06562f..30eff7d 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp
@@ -184,7 +184,7 @@
         return signalPassFailure();
       }
 
-      bool lowerToAVX2 = hasAVX2Feature(variantOp);
+      bool lowerToAVX2 = hasAVX2Feature(variantOp.getTarget());
       if (!testLoweringConfiguration) {
         switch (translationInfo.value().getDispatchLoweringPassPipeline()) {
           case IREE::Codegen::DispatchLoweringPassPipeline::CPUDefault:
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp
index bf26b16..959318f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp
@@ -26,8 +26,8 @@
 namespace iree_compiler {
 
 const TargetMLTransformInfo TargetMLTransformInfo::getTargetMLTransformInfo(
-    IREE::HAL::ExecutableVariantOp variantOp) {
-  if (isRISCV(variantOp)) {
+    IREE::HAL::ExecutableTargetAttr targetAttr) {
+  if (isRISCV(targetAttr)) {
     return RISCVTargetMLTransformInfo();
   }
 
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h
index bbdf4d3..06ffd6f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h
@@ -9,7 +9,7 @@
 
 #include <limits>
 
-#include "iree/compiler/Dialect/HAL/IR/HALOps.h"
+#include "iree/compiler/Dialect/HAL/IR/HALTypes.h"
 
 namespace mlir {
 namespace iree_compiler {
@@ -22,7 +22,7 @@
       std::numeric_limits<unsigned>::max();
 
   static const TargetMLTransformInfo getTargetMLTransformInfo(
-      IREE::HAL::ExecutableVariantOp variantOp);
+      IREE::HAL::ExecutableTargetAttr targetAttr);
 };
 
 }  // namespace iree_compiler
diff --git a/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp b/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp
index 03ae9f6..a53f5f2 100644
--- a/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp
+++ b/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp
@@ -71,11 +71,8 @@
   return exportOps;
 }
 
-/// Returns the StringAttr with the name `stringAttr` in the configuration of
-/// `variantOp`, in found.
-static Optional<StringAttr> getConfigStringAttr(
-    IREE::HAL::ExecutableVariantOp variantOp, StringRef stringAttr) {
-  IREE::HAL::ExecutableTargetAttr targetAttr = variantOp.getTarget();
+Optional<StringAttr> getConfigStringAttr(
+    IREE::HAL::ExecutableTargetAttr targetAttr, StringRef stringAttr) {
   if (!targetAttr) return llvm::None;
   auto config = targetAttr.getConfiguration();
   if (!config) return llvm::None;
@@ -84,41 +81,57 @@
   return attr;
 }
 
-/// Returns the LLVM Target triple associated with the `hal.executable.variant`
-/// operation if set.
-static Optional<llvm::Triple> getTargetTriple(
-    IREE::HAL::ExecutableVariantOp variantOp) {
-  auto triple = getConfigStringAttr(variantOp, "target_triple");
+Optional<IntegerAttr> getConfigIntegerAttr(
+    IREE::HAL::ExecutableTargetAttr targetAttr, StringRef integerAttr) {
+  if (!targetAttr) return llvm::None;
+  auto config = targetAttr.getConfiguration();
+  if (!config) return llvm::None;
+  auto attr = config.getAs<IntegerAttr>(integerAttr);
+  if (!attr) return llvm::None;
+  return attr;
+}
+
+Optional<llvm::Triple> getTargetTriple(
+    IREE::HAL::ExecutableTargetAttr targetAttr) {
+  auto triple = getConfigStringAttr(targetAttr, "target_triple");
   if (!triple) return llvm::None;
   return llvm::Triple(triple.value().str());
 }
 
 /// Returns the CPU target features associated with the `hal.executable.variant`
 /// operation, if set.
-static Optional<StringRef> getCpuFeatures(
-    IREE::HAL::ExecutableVariantOp variantOp) {
-  auto cpuFeatures = getConfigStringAttr(variantOp, "cpu_features");
+Optional<StringRef> getCpuFeatures(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  auto cpuFeatures = getConfigStringAttr(targetAttr, "cpu_features");
   if (!cpuFeatures) return llvm::None;
   return cpuFeatures->getValue();
 }
 
-bool isX86(IREE::HAL::ExecutableVariantOp variantOp) {
-  Optional<llvm::Triple> triple = getTargetTriple(variantOp);
+bool isX86(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  Optional<llvm::Triple> triple = getTargetTriple(targetAttr);
   return triple && triple.value().isX86();
 }
 
-bool isAArch64(IREE::HAL::ExecutableVariantOp variantOp) {
-  Optional<llvm::Triple> triple = getTargetTriple(variantOp);
+bool isAArch64(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  Optional<llvm::Triple> triple = getTargetTriple(targetAttr);
   return triple && triple.value().isAArch64();
 }
 
+bool isRISCV(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  Optional<llvm::Triple> triple = getTargetTriple(targetAttr);
+  return triple && triple.value().isRISCV();
+}
+
+bool isVMVXBackend(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  return targetAttr.getBackend().getValue().startswith("vmvx");
+}
+
 // TODO(dcaballe): If we have to check for a significantly large number of
 // features in the future, we may want to consider a persistent state to carry
 // over processed HAL information or keeping the TTI instance alive and query
 // subtarget features data structure.
-static bool hasFeature(IREE::HAL::ExecutableVariantOp variantOp,
+static bool hasFeature(IREE::HAL::ExecutableTargetAttr targetAttr,
                        StringRef feature) {
-  Optional<StringRef> features = getCpuFeatures(variantOp);
+  Optional<StringRef> features = getCpuFeatures(targetAttr);
   if (!features) {
     return false;
   }
@@ -136,29 +149,20 @@
   return false;
 }
 
-/// Returns true if the 'variantOp' contains '+avx2' in its cpu features.
-bool hasAVX2Feature(IREE::HAL::ExecutableVariantOp variantOp) {
-  return hasFeature(variantOp, "+avx2");
+bool hasAVX2Feature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  return hasFeature(targetAttr, "+avx2");
 }
 
-/// Returns true if the 'variantOp' contains '+v' in its cpu features.
-bool hasVFeature(IREE::HAL::ExecutableVariantOp variantOp) {
-  return hasFeature(variantOp, "+v");
+bool hasVFeature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  return hasFeature(targetAttr, "+v");
 }
 
-/// Returns true if the 'variantOp' contains '+zve32x' in its cpu features.
-bool hasZve32xFeature(IREE::HAL::ExecutableVariantOp variantOp) {
-  return hasFeature(variantOp, "+zve32x");
+bool hasZve32xFeature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  return hasFeature(targetAttr, "+zve32x");
 }
 
-/// Returns true if the 'variantOp' contains '+zve64x' in its cpu features.
-bool hasZve64xFeature(IREE::HAL::ExecutableVariantOp variantOp) {
-  return hasFeature(variantOp, "+zve64x");
-}
-
-bool isRISCV(IREE::HAL::ExecutableVariantOp variantOp) {
-  Optional<llvm::Triple> triple = getTargetTriple(variantOp);
-  return triple && triple.value().isRISCV();
+bool hasZve64xFeature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+  return hasFeature(targetAttr, "+zve64x");
 }
 
 bool isReadOnly(Value v) {
diff --git a/compiler/src/iree/compiler/Codegen/Utils/Utils.h b/compiler/src/iree/compiler/Codegen/Utils/Utils.h
index 506f707..47778b8 100644
--- a/compiler/src/iree/compiler/Codegen/Utils/Utils.h
+++ b/compiler/src/iree/compiler/Codegen/Utils/Utils.h
@@ -43,28 +43,40 @@
 /// failure.
 FailureOr<IREE::HAL::ExecutableVariantOp> getExecutableVariantOp(Operation *op);
 
+/// Returns the StringAttr with the name `stringAttr` in the `targetAttr`, if
+/// found.
+Optional<StringAttr> getConfigStringAttr(
+    IREE::HAL::ExecutableTargetAttr targetAttr, StringRef stringAttr);
+
+/// Returns the IntegerAttr with the name `integerAttr` in the `targetAttr`, if
+/// found.
+Optional<IntegerAttr> getConfigIntegerAttr(
+    IREE::HAL::ExecutableTargetAttr targetAttr, StringRef integerAttr);
+
+/// Returns the LLVM Target triple associated with the `targetAttr`, if set.
+Optional<llvm::Triple> getTargetTriple(
+    IREE::HAL::ExecutableTargetAttr targetAttr);
+
+/// Returns the CPU target features associated with the `targetAttr`, if set.
+Optional<StringRef> getCpuFeatures(IREE::HAL::ExecutableTargetAttr targetAttr);
+
 /// Methods to get target information.
-bool isX86(IREE::HAL::ExecutableVariantOp variantOp);
-
-bool isAArch64(IREE::HAL::ExecutableVariantOp variantOp);
-
-bool isRISCV(IREE::HAL::ExecutableVariantOp variantOp);
-
-inline bool isVMVXBackend(IREE::HAL::ExecutableVariantOp variantOp) {
-  return variantOp.getTarget().getBackend().getValue().startswith("vmvx");
-}
+bool isX86(IREE::HAL::ExecutableTargetAttr targetAttr);
+bool isAArch64(IREE::HAL::ExecutableTargetAttr targetAttr);
+bool isRISCV(IREE::HAL::ExecutableTargetAttr targetAttr);
+bool isVMVXBackend(IREE::HAL::ExecutableTargetAttr targetAttr);
 
 /// Returns true if the 'variantOp' contains '+avx2' in its cpu features.
-bool hasAVX2Feature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasAVX2Feature(IREE::HAL::ExecutableTargetAttr targetAttr);
 
 /// Returns true if the 'variantOp' contains '+v' in its cpu features.
-bool hasVFeature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasVFeature(IREE::HAL::ExecutableTargetAttr targetAttr);
 
 /// Returns true if the 'variantOp' contains '+zve32x' in its cpu features.
-bool hasZve32xFeature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasZve32xFeature(IREE::HAL::ExecutableTargetAttr targetAttr);
 
 /// Returns true if the 'variantOp' contains '+zve64x' in its cpu features.
-bool hasZve64xFeature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasZve64xFeature(IREE::HAL::ExecutableTargetAttr targetAttr);
 
 /// Checks if a tensor value is generated from a read-only object, like
 /// and interface binding with read-only attribute or from an `arith.constant`