[llvm] [LLVM] Remove SVEIntrinsicOpts pass. (PR #210368)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 17 09:37:03 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Paul Walker (paulwalker-arm)

<details>
<summary>Changes</summary>

Most functionality has been moved elsewhere. What remains is meaningless because it relies on ptrue intrinsics that will be simplified to `splat (i1 true)` before the pass sees them.

---

Patch is 30.11 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210368.diff


8 Files Affected:

- (modified) llvm/docs/WritingAnLLVMPass.md (-1) 
- (modified) llvm/lib/Target/AArch64/AArch64.h (-2) 
- (modified) llvm/lib/Target/AArch64/AArch64TargetMachine.cpp (-11) 
- (modified) llvm/lib/Target/AArch64/CMakeLists.txt (-1) 
- (removed) llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp (-294) 
- (modified) llvm/test/CodeGen/AArch64/O3-pipeline.ll (-7) 
- (removed) llvm/test/CodeGen/AArch64/sve-coalesce-ptrue-intrinsics.ll (-184) 
- (modified) llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn (-1) 


``````````diff
diff --git a/llvm/docs/WritingAnLLVMPass.md b/llvm/docs/WritingAnLLVMPass.md
index 91f81a3e0c048..a4f4938cb455e 100644
--- a/llvm/docs/WritingAnLLVMPass.md
+++ b/llvm/docs/WritingAnLLVMPass.md
@@ -635,7 +635,6 @@ Pre-ISel Intrinsic Lowering
 FunctionPass Manager
   Expand IR instructions
   Expand Atomic instructions
-SVE intrinsics optimizations
   FunctionPass Manager
     Dominator Tree Construction
 FunctionPass Manager
diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h
index 86a6635a37497..9fc0d7fe96ee3 100644
--- a/llvm/lib/Target/AArch64/AArch64.h
+++ b/llvm/lib/Target/AArch64/AArch64.h
@@ -78,7 +78,6 @@ FunctionPass *createAArch64CollectLOHPass();
 FunctionPass *createSMEPeepholeOptPass();
 FunctionPass *createMachineSMEABIPass(CodeGenOptLevel);
 FunctionPass *createAArch64SRLTDefineSuperRegsLegacyPass();
-ModulePass *createSVEIntrinsicOptsPass();
 Pass *createSVEShuffleOptsPass();
 InstructionSelector *
 createAArch64InstructionSelector(const AArch64TargetMachine &,
@@ -203,7 +202,6 @@ void initializeLDTLSCleanupPass(PassRegistry &);
 void initializeSMEPeepholeOptPass(PassRegistry &);
 void initializeMachineSMEABIPass(PassRegistry &);
 void initializeAArch64SRLTDefineSuperRegsLegacyPass(PassRegistry &);
-void initializeSVEIntrinsicOptsPass(PassRegistry &);
 void initializeSVEShuffleOptsPass(PassRegistry &);
 void initializeAArch64Arm64ECCallLoweringPass(PassRegistry &);
 
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index d4801e68b9812..2b4d50a89ff59 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -161,11 +161,6 @@ static cl::opt<int> EnableGlobalISelAtO(
     cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"),
     cl::init(0));
 
-static cl::opt<bool>
-    EnableSVEIntrinsicOpts("aarch64-enable-sve-intrinsic-opts", cl::Hidden,
-                           cl::desc("Enable SVE intrinsic opts"),
-                           cl::init(true));
-
 static cl::opt<bool>
     EnableSMEPeepholeOpt("enable-aarch64-sme-peephole-opt", cl::init(true),
                          cl::Hidden,
@@ -279,7 +274,6 @@ LLVMInitializeAArch64Target() {
   initializeMachineSMEABIPass(PR);
   initializeAArch64SRLTDefineSuperRegsLegacyPass(PR);
   initializeSMEPeepholeOptPass(PR);
-  initializeSVEIntrinsicOptsPass(PR);
   initializeAArch64SpeculationHardeningPass(PR);
   initializeAArch64SLSHardeningLegacyPass(PR);
   initializeAArch64StackTaggingPass(PR);
@@ -652,11 +646,6 @@ void AArch64PassConfig::addIRPasses() {
   // ourselves.
   addPass(createAtomicExpandLegacyPass());
 
-  // Expand any SVE vector library calls that we can't code generate directly.
-  if (EnableSVEIntrinsicOpts &&
-      TM->getOptLevel() != CodeGenOptLevel::None)
-    addPass(createSVEIntrinsicOptsPass());
-
   // Cmpxchg instructions are often used with a subsequent comparison to
   // determine whether it succeeded. We can exploit existing control-flow in
   // ldrex/strex loops to simplify this, but it needs tidying up.
diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt
index fadf5ce60907c..12a2214f8e58e 100644
--- a/llvm/lib/Target/AArch64/CMakeLists.txt
+++ b/llvm/lib/Target/AArch64/CMakeLists.txt
@@ -92,7 +92,6 @@ add_llvm_target(AArch64CodeGen
   AArch64TargetObjectFile.cpp
   AArch64TargetTransformInfo.cpp
   SMEPeepholeOpt.cpp
-  SVEIntrinsicOpts.cpp
   SVEShuffleOpts.cpp
   MachineSMEABIPass.cpp
   AArch64SRLTDefineSuperRegs.cpp
diff --git a/llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp b/llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp
deleted file mode 100644
index d485f66e2126e..0000000000000
--- a/llvm/lib/Target/AArch64/SVEIntrinsicOpts.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-//===----- SVEIntrinsicOpts - SVE ACLE Intrinsics Opts --------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Performs general IR level optimizations on SVE intrinsics.
-//
-// This pass performs the following optimizations:
-//
-// - removes unnecessary ptrue intrinsics (llvm.aarch64.sve.ptrue), e.g:
-//     %1 = @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
-//     %2 = @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
-//     ; (%1 can be replaced with a reinterpret of %2)
-//
-// - optimizes ptest intrinsics where the operands are being needlessly
-//   converted to and from svbool_t.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AArch64.h"
-#include "Utils/AArch64BaseInfo.h"
-#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/IntrinsicsAArch64.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/PatternMatch.h"
-#include "llvm/InitializePasses.h"
-#include <optional>
-
-using namespace llvm;
-using namespace llvm::PatternMatch;
-
-#define DEBUG_TYPE "aarch64-sve-intrinsic-opts"
-
-namespace {
-struct SVEIntrinsicOpts : public ModulePass {
-  static char ID; // Pass identification, replacement for typeid
-  SVEIntrinsicOpts() : ModulePass(ID) {}
-
-  bool runOnModule(Module &M) override;
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-private:
-  bool coalescePTrueIntrinsicCalls(BasicBlock &BB,
-                                   SmallSetVector<IntrinsicInst *, 4> &PTrues);
-  bool optimizePTrueIntrinsicCalls(SmallSetVector<Function *, 4> &Functions);
-};
-} // end anonymous namespace
-
-void SVEIntrinsicOpts::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.addRequired<DominatorTreeWrapperPass>();
-  AU.setPreservesCFG();
-}
-
-char SVEIntrinsicOpts::ID = 0;
-static const char *name = "SVE intrinsics optimizations";
-INITIALIZE_PASS_BEGIN(SVEIntrinsicOpts, DEBUG_TYPE, name, false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
-INITIALIZE_PASS_END(SVEIntrinsicOpts, DEBUG_TYPE, name, false, false)
-
-ModulePass *llvm::createSVEIntrinsicOptsPass() {
-  return new SVEIntrinsicOpts();
-}
-
-/// Checks if a ptrue intrinsic call is promoted. The act of promoting a
-/// ptrue will introduce zeroing. For example:
-///
-///     %1 = <vscale x 4 x i1> call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
-///     %2 = <vscale x 16 x i1> call @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1> %1)
-///     %3 = <vscale x 8 x i1> call @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %2)
-///
-/// %1 is promoted, because it is converted:
-///
-///     <vscale x 4 x i1> => <vscale x 16 x i1> => <vscale x 8 x i1>
-///
-/// via a sequence of the SVE reinterpret intrinsics convert.{to,from}.svbool.
-static bool isPTruePromoted(IntrinsicInst *PTrue) {
-  // Find all users of this intrinsic that are calls to convert-to-svbool
-  // reinterpret intrinsics.
-  SmallVector<IntrinsicInst *, 4> ConvertToUses;
-  for (User *User : PTrue->users()) {
-    if (match(User, m_Intrinsic<Intrinsic::aarch64_sve_convert_to_svbool>())) {
-      ConvertToUses.push_back(cast<IntrinsicInst>(User));
-    }
-  }
-
-  // If no such calls were found, this is ptrue is not promoted.
-  if (ConvertToUses.empty())
-    return false;
-
-  // Otherwise, try to find users of the convert-to-svbool intrinsics that are
-  // calls to the convert-from-svbool intrinsic, and would result in some lanes
-  // being zeroed.
-  const auto *PTrueVTy = cast<ScalableVectorType>(PTrue->getType());
-  for (IntrinsicInst *ConvertToUse : ConvertToUses) {
-    for (User *User : ConvertToUse->users()) {
-      auto *IntrUser = dyn_cast<IntrinsicInst>(User);
-      if (IntrUser && IntrUser->getIntrinsicID() ==
-                          Intrinsic::aarch64_sve_convert_from_svbool) {
-        const auto *IntrUserVTy = cast<ScalableVectorType>(IntrUser->getType());
-
-        // Would some lanes become zeroed by the conversion?
-        if (IntrUserVTy->getElementCount().getKnownMinValue() >
-            PTrueVTy->getElementCount().getKnownMinValue())
-          // This is a promoted ptrue.
-          return true;
-      }
-    }
-  }
-
-  // If no matching calls were found, this is not a promoted ptrue.
-  return false;
-}
-
-/// Attempts to coalesce ptrues in a basic block.
-bool SVEIntrinsicOpts::coalescePTrueIntrinsicCalls(
-    BasicBlock &BB, SmallSetVector<IntrinsicInst *, 4> &PTrues) {
-  if (PTrues.size() <= 1)
-    return false;
-
-  // Find the ptrue with the most lanes.
-  auto *MostEncompassingPTrue =
-      *llvm::max_element(PTrues, [](auto *PTrue1, auto *PTrue2) {
-        auto *PTrue1VTy = cast<ScalableVectorType>(PTrue1->getType());
-        auto *PTrue2VTy = cast<ScalableVectorType>(PTrue2->getType());
-        return PTrue1VTy->getElementCount().getKnownMinValue() <
-               PTrue2VTy->getElementCount().getKnownMinValue();
-      });
-
-  // Remove the most encompassing ptrue, as well as any promoted ptrues, leaving
-  // behind only the ptrues to be coalesced.
-  PTrues.remove(MostEncompassingPTrue);
-  PTrues.remove_if(isPTruePromoted);
-
-  // Hoist MostEncompassingPTrue to the start of the basic block. It is always
-  // safe to do this, since ptrue intrinsic calls are guaranteed to have no
-  // predecessors.
-  MostEncompassingPTrue->moveBefore(BB, BB.getFirstInsertionPt());
-
-  LLVMContext &Ctx = BB.getContext();
-  IRBuilder<> Builder(Ctx);
-  Builder.SetInsertPoint(&BB, ++MostEncompassingPTrue->getIterator());
-
-  auto *MostEncompassingPTrueVTy =
-      cast<VectorType>(MostEncompassingPTrue->getType());
-  auto *ConvertToSVBool = Builder.CreateIntrinsicWithoutFolding(
-      Intrinsic::aarch64_sve_convert_to_svbool, {MostEncompassingPTrueVTy},
-      {MostEncompassingPTrue});
-
-  bool ConvertFromCreated = false;
-  for (auto *PTrue : PTrues) {
-    auto *PTrueVTy = cast<VectorType>(PTrue->getType());
-
-    // Only create the converts if the types are not already the same, otherwise
-    // just use the most encompassing ptrue.
-    if (MostEncompassingPTrueVTy != PTrueVTy) {
-      ConvertFromCreated = true;
-
-      Builder.SetInsertPoint(&BB, ++ConvertToSVBool->getIterator());
-      auto *ConvertFromSVBool =
-          Builder.CreateIntrinsic(Intrinsic::aarch64_sve_convert_from_svbool,
-                                  {PTrueVTy}, {ConvertToSVBool});
-      PTrue->replaceAllUsesWith(ConvertFromSVBool);
-    } else
-      PTrue->replaceAllUsesWith(MostEncompassingPTrue);
-
-    PTrue->eraseFromParent();
-  }
-
-  // We never used the ConvertTo so remove it
-  if (!ConvertFromCreated)
-    ConvertToSVBool->eraseFromParent();
-
-  return true;
-}
-
-/// The goal of this function is to remove redundant calls to the SVE ptrue
-/// intrinsic in each basic block within the given functions.
-///
-/// SVE ptrues have two representations in LLVM IR:
-/// - a logical representation -- an arbitrary-width scalable vector of i1s,
-///   i.e. <vscale x N x i1>.
-/// - a physical representation (svbool, <vscale x 16 x i1>) -- a 16-element
-///   scalable vector of i1s, i.e. <vscale x 16 x i1>.
-///
-/// The SVE ptrue intrinsic is used to create a logical representation of an SVE
-/// predicate. Suppose that we have two SVE ptrue intrinsic calls: P1 and P2. If
-/// P1 creates a logical SVE predicate that is at least as wide as the logical
-/// SVE predicate created by P2, then all of the bits that are true in the
-/// physical representation of P2 are necessarily also true in the physical
-/// representation of P1. P1 'encompasses' P2, therefore, the intrinsic call to
-/// P2 is redundant and can be replaced by an SVE reinterpret of P1 via
-/// convert.{to,from}.svbool.
-///
-/// Currently, this pass only coalesces calls to SVE ptrue intrinsics
-/// if they match the following conditions:
-///
-/// - the call to the intrinsic uses either the SV_ALL or SV_POW2 patterns.
-///   SV_ALL indicates that all bits of the predicate vector are to be set to
-///   true. SV_POW2 indicates that all bits of the predicate vector up to the
-///   largest power-of-two are to be set to true.
-/// - the result of the call to the intrinsic is not promoted to a wider
-///   predicate. In this case, keeping the extra ptrue leads to better codegen
-///   -- coalescing here would create an irreducible chain of SVE reinterprets
-///   via convert.{to,from}.svbool.
-///
-/// EXAMPLE:
-///
-///     %1 = <vscale x 8 x i1> ptrue(i32 SV_ALL)
-///     ; Logical:  <1, 1, 1, 1, 1, 1, 1, 1>
-///     ; Physical: <1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0>
-///     ...
-///
-///     %2 = <vscale x 4 x i1> ptrue(i32 SV_ALL)
-///     ; Logical:  <1, 1, 1, 1>
-///     ; Physical: <1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0>
-///     ...
-///
-/// Here, %2 can be replaced by an SVE reinterpret of %1, giving, for instance:
-///
-///     %1 = <vscale x 8 x i1> ptrue(i32 i31)
-///     %2 = <vscale x 16 x i1> convert.to.svbool(<vscale x 8 x i1> %1)
-///     %3 = <vscale x 4 x i1> convert.from.svbool(<vscale x 16 x i1> %2)
-///
-bool SVEIntrinsicOpts::optimizePTrueIntrinsicCalls(
-    SmallSetVector<Function *, 4> &Functions) {
-  bool Changed = false;
-
-  for (auto *F : Functions) {
-    for (auto &BB : *F) {
-      SmallSetVector<IntrinsicInst *, 4> SVAllPTrues;
-      SmallSetVector<IntrinsicInst *, 4> SVPow2PTrues;
-
-      // For each basic block, collect the used ptrues and try to coalesce them.
-      for (Instruction &I : BB) {
-        if (I.use_empty())
-          continue;
-
-        auto *IntrI = dyn_cast<IntrinsicInst>(&I);
-        if (!IntrI || IntrI->getIntrinsicID() != Intrinsic::aarch64_sve_ptrue)
-          continue;
-
-        const auto PTruePattern =
-            cast<ConstantInt>(IntrI->getOperand(0))->getZExtValue();
-
-        if (PTruePattern == AArch64SVEPredPattern::all)
-          SVAllPTrues.insert(IntrI);
-        if (PTruePattern == AArch64SVEPredPattern::pow2)
-          SVPow2PTrues.insert(IntrI);
-      }
-
-      Changed |= coalescePTrueIntrinsicCalls(BB, SVAllPTrues);
-      Changed |= coalescePTrueIntrinsicCalls(BB, SVPow2PTrues);
-    }
-  }
-
-  return Changed;
-}
-
-bool SVEIntrinsicOpts::runOnModule(Module &M) {
-  bool Changed = false;
-  SmallSetVector<Function *, 4> Functions;
-
-  // Check for SVE intrinsic declarations first so that we only iterate over
-  // relevant functions. Where an appropriate declaration is found, store the
-  // function(s) where it is used so we can target these only.
-  for (auto &F : M.getFunctionList()) {
-    if (!F.isDeclaration())
-      continue;
-
-    switch (F.getIntrinsicID()) {
-    case Intrinsic::aarch64_sve_ptrue:
-      for (User *U : F.users())
-        Functions.insert(cast<Instruction>(U)->getFunction());
-      break;
-    default:
-      break;
-    }
-  }
-
-  if (!Functions.empty())
-    Changed |= optimizePTrueIntrinsicCalls(Functions);
-
-  return Changed;
-}
diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll
index 213559d8e24e8..d3f43f8fbd6ea 100644
--- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll
+++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll
@@ -28,10 +28,6 @@
 ; CHECK-NEXT:     FunctionPass Manager
 ; CHECK-NEXT:       Expand IR instructions
 ; CHECK-NEXT:       Expand Atomic instructions
-; CHECK-NEXT:     SVE intrinsics optimizations
-; CHECK-NEXT:       FunctionPass Manager
-; CHECK-NEXT:         Dominator Tree Construction
-; CHECK-NEXT:     FunctionPass Manager
 ; CHECK-NEXT:       Simplify the CFG
 ; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Natural Loop Information
@@ -264,9 +260,6 @@
 ; CHECK-NEXT:       Machine Optimization Remark Emitter
 ; CHECK-NEXT:       AArch64 Assembly Printer
 ; CHECK-NEXT:       Free MachineFunction
-; CHECK-NEXT: Pass Arguments:  -domtree
-; CHECK-NEXT:   FunctionPass Manager
-; CHECK-NEXT:     Dominator Tree Construction
 ; CHECK-NEXT: Pass Arguments:  -assumption-cache-tracker -targetlibinfo -domtree -loops -scalar-evolution -stack-safety-local
 ; CHECK-NEXT: Assumption Cache Tracker
 ; CHECK-NEXT: Target Library Information
diff --git a/llvm/test/CodeGen/AArch64/sve-coalesce-ptrue-intrinsics.ll b/llvm/test/CodeGen/AArch64/sve-coalesce-ptrue-intrinsics.ll
deleted file mode 100644
index 3fea2cc20971e..0000000000000
--- a/llvm/test/CodeGen/AArch64/sve-coalesce-ptrue-intrinsics.ll
+++ /dev/null
@@ -1,184 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -aarch64-sve-intrinsic-opts -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
-
-declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 immarg)
-declare <vscale x 2 x i1> @llvm.aarch64.sve.ptrue.nxv2i1(i32 immarg)
-declare <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 immarg)
-declare <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 immarg)
-
-declare <vscale x 16 x i32> @llvm.aarch64.sve.ld1.nxv16i32(<vscale x 16 x i1>, ptr)
-declare <vscale x 2 x i32> @llvm.aarch64.sve.ld1.nxv2i32(<vscale x 2 x i1>, ptr)
-declare <vscale x 4 x i32> @llvm.aarch64.sve.ld1.nxv4i32(<vscale x 4 x i1>, ptr)
-declare <vscale x 8 x i16> @llvm.aarch64.sve.ld1.nxv8i16(<vscale x 8 x i1>, ptr)
-declare <vscale x 8 x i32> @llvm.aarch64.sve.ld1.nxv8i32(<vscale x 8 x i1>, ptr)
-
-declare <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1>)
-declare <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1>)
-
-; Two calls to the SVE ptrue intrinsic. %1 is redundant, and can be expressed as an SVE reinterpret of %3 via
-; convert.{to,from}.svbool.
-define <vscale x 8 x i32> @coalesce_test_basic(ptr %addr) {
-; CHECK-LABEL: @coalesce_test_basic(
-; CHECK-NEXT:    [[TMP1:%.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
-; CHECK-NEXT:    [[TMP2:%.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> [[TMP1]])
-; CHECK-NEXT:    [[TMP3:%.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[TMP2]])
-; CHECK-NEXT:    [[TMP4:%.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.ld1.nxv4i32.p0(<vscale x 4 x i1> [[TMP3]], ptr [[ADDR:%.*]])
-; CHECK-NEXT:    [[TMP5:%.*]] = call <vscale x 8 x i32> @llvm.aarch64.sve.ld1.nxv8i32.p0(<vscale x 8 x i1> [[TMP1]], ptr [[ADDR]])
-; CHECK-NEXT:    ret <vscale x 8 x i32> [[TMP5]]
-;
-  %1 = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
-  %2 = call <vscale x 4 x i32> @llvm.aarch64.sve.ld1.nxv4i32(<vscale x 4 x i1> %1, ptr %addr)
-  %3 = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 31)
-  %4 = call <vscale x 8 x i32> @llvm.aarch64.sve.ld1.nxv8i32(<vscale x 8 x i1> %3, ptr %addr)
-  ret <vscale x 8 x i32> %4
-}
-
-; Two calls to the SVE ptrue intrinsic with the SV_POW2 pattern. This should reduce to the same output as
-; coalesce_test_basic.
-define <vscale x 8 x i32> @coalesce_test_pow2(ptr %addr) {
-; CHECK-LABEL: @coalesce_test_pow2(
-; CHECK-NEXT:    [[TMP1:%.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 0)
-; CHECK-NEXT:    [[TMP2:%.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> [[TMP1]])
-; CHECK-NEXT:    [[TMP3:%.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[TMP2]])
-; CHECK-NEXT:    [[TMP4:%.*]] = call <vscale x 4 x i32> @llvm.aarch64.sve.ld1.nxv4i32.p0(<vscale x 4 x i1> [[TMP3]], ptr [[ADDR:%.*]])
-; CHECK-NEXT:    [[TMP5:%.*]] = call <vscale x 8 x i32> @llvm.aarch64.sve.ld1.nxv8i32.p0(<vscale x 8 x i1> [[TMP1]], ptr [[ADDR]])
-; CHECK-NEXT:    ret <vscale x 8 x i32> [[TMP5]]
-;
-  %1 = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 0)
-  %2 = call <vscale x 4 x i32> @llvm.aarch64.sve.ld1.nxv4i32(<vscale x 4 x i1> %1, ptr %addr)
-  %3 = call <vscale x 8 x i1> @llvm.aarch64.sve.ptrue.nxv8i1(i32 0)
-  %4 = call <vscale x 8 x i32> @llvm.aarch64.sve.ld1.nxv8i32(<vscale x 8 x i1> %3, ptr %addr)
-  ret <vscale x 8 x i32> %4
-}
-
-; Four calls to the SVE ptrue intrinsic; two with the SV_ALL patterns, and two with the SV_POW2 pattern. The
-; two SV_ALL ptrue intrinsics should be coalesced, and th...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list