[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