[llvm] [AArch64] Hint regalloc to choose distinct predicate for MATCH/CMP (PR #190139)
Mikael Holmen via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 06:42:43 PDT 2026
================
@@ -1115,6 +1115,55 @@ unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
}
}
+static bool HandleMatchCmpPredicateHint(
+ Register VirtReg, ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints, const VirtRegMap *VRM,
+ const MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
+ const AArch64Subtarget &ST, const LiveRegMatrix *Matrix) {
+ const TargetRegisterClass *RegRC = MRI.getRegClass(VirtReg);
+ if (!ST.useDistinctPredicateDstReg() ||
+ !AArch64::PPRRegClass.hasSubClassEq(RegRC) || !MRI.hasOneDef(VirtReg) ||
+ Order.size() < 2)
+ return false;
+
+ const MachineInstr *DefInst = MRI.getOneDef(VirtReg)->getParent();
+ if ((TII.get(DefInst->getOpcode()).TSFlags &
+ AArch64::DestructiveInstTypeMask) != AArch64::DestructivePredicate)
+ return false;
+
+ Register Op1Reg = DefInst->getOperand(1).getReg();
+ if (Op1Reg.isVirtual())
+ Op1Reg = VRM->getPhys(Op1Reg);
+
+ // If no register is allocated for the general-predicate, it's not yet
+ // possible to choose a distinct register.
+ if (!Op1Reg.isValid())
+ return false;
+
+ // Move Op1Reg as the least preferred register.
+ //
+ // This might result in callee-save spills when the function takes/returns
+ // arguments in SVE registers (i.e. needs to preserve p4-p15) and can't reuse
+ // p0-p3. That's why we limit it to non-callee saved registers or to
+ // callee-saved registers that have already been allocated for other uses in
+ // the function.
+ DenseSet<unsigned> CSRs;
+ for (unsigned I = 0;; ++I) {
+ Register R = MRI.getCalleeSavedRegs()[I];
+ if (!R.isValid())
+ break;
+ if (AArch64::PPRRegClass.contains(R))
+ CSRs.insert(R);
+ }
+
+ Hints.append(Order.begin(), Order.end());
+ llvm::stable_sort(Hints, [&](Register A, Register B) {
----------------
mikaelholmen wrote:
Hi @sdesmalen-arm
Wwith EXPENSIVE_CHECKS I currently see 85 failing AArch64 lit tests. One example:
```
********************
Testing: 0.. 10.. 20.. 30
FAIL: LLVM :: CodeGen/AArch64/sve2-intrinsics-reinterpret.ll (32364 of 98064)
******************** TEST 'LLVM :: CodeGen/AArch64/sve2-intrinsics-reinterpret.ll' FAILED ********************
Exit Code: 2
Command Output (stdout):
--
# RUN: at line 2
/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc -mtriple=aarch64-linux-gnu -mattr=+sve2 < /repo/llvm-main-expensive-checks/llvm/test/CodeGen/AArch64/sve2-intrinsics-reinterpret.ll | /repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/FileCheck /repo/llvm-main-expensive-checks/llvm/test/CodeGen/AArch64/sve2-intrinsics-reinterpret.ll
# executed command: /repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc -mtriple=aarch64-linux-gnu -mattr=+sve2
# .---command stderr------------
# | [...]/include/c++/13.3.0/bits/stl_algo.h:5117:
# | In function:
# | void std::stable_sort(_RandomAccessIterator, _RandomAccessIterator,
# | _Compare) [_RandomAccessIterator = unsigned short *, _Compare = (lambda
# | at
# | /repo/llvm-main-expensive-checks/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp:1160:28)]
# |
# | Error: comparison doesn't meet irreflexive requirements, assert(!(a < a)).
# |
# | Objects involved in the operation:
# | instance "functor" @ 0x7fffd1fcc190 {
# | }
# | iterator::value_type "ordered type" {
# | }
# | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
# | Stack dump:
# | 0. Program arguments: /repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc -mtriple=aarch64-linux-gnu -mattr=+sve2
# | 1. Running pass 'Function Pass Manager' on module '<stdin>'.
# | 2. Running pass 'Greedy Register Allocator' on function '@cmpeq_d_fun'
# | #0 0x0000561e9988e956 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x92c1956)
# | #1 0x0000561e9988b781 llvm::sys::RunSignalHandlers() (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x92be781)
# | #2 0x0000561e9988f789 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
# | #3 0x00007fdf233ea990 __restore_rt (/lib64/libpthread.so.0+0x12990)
# | #4 0x00007fdf20d8a5af raise (/lib64/libc.so.6+0x4e5af)
# | #5 0x00007fdf20d5dee5 abort (/lib64/libc.so.6+0x21ee5)
# | #6 0x0000561e9a8adef3 (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0xa2e0ef3)
# | #7 0x0000561e95f8a5a1 llvm::AArch64RegisterInfo::getRegAllocationHints(llvm::Register, llvm::ArrayRef<unsigned short>, llvm::SmallVectorImpl<unsigned short>&, llvm::MachineFunction const&, llvm::VirtRegMap const*, llvm::LiveRegMatrix const*) const AArch64RegisterInfo.cpp:0:0
# | #8 0x0000561e984d5ee2 llvm::AllocationOrder::create(llvm::Register, llvm::VirtRegMap const&, llvm::RegisterClassInfo const&, llvm::LiveRegMatrix const*) AllocationOrder.cpp:0:0
# | #9 0x0000561e9850706a llvm::RAGreedy::selectOrSplitImpl(llvm::LiveInterval const&, llvm::SmallVectorImpl<llvm::Register>&, llvm::SmallSet<llvm::Register, 16u, std::less<llvm::Register>>&, llvm::SmallVector<std::pair<llvm::LiveInterval const*, llvm::MCRegister>, 8u>&, unsigned int) RegAllocGreedy.cpp:0:0
# | #10 0x0000561e9850791e llvm::RAGreedy::selectOrSplit(llvm::LiveInterval const&, llvm::SmallVectorImpl<llvm::Register>&) RegAllocGreedy.cpp:0:0
# | #11 0x0000561e984d1cea llvm::RegAllocBase::allocatePhysRegs() (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x7f04cea)
# | #12 0x0000561e984f949d llvm::RAGreedy::run(llvm::MachineFunction&) RegAllocGreedy.cpp:0:0
# | #13 0x0000561e9850c71a (anonymous namespace)::RAGreedyLegacy::runOnMachineFunction(llvm::MachineFunction&) RegAllocGreedy.cpp:0:0
# | #14 0x0000561e98241747 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x7c74747)
# | #15 0x0000561e9888a9c4 llvm::FPPassManager::runOnFunction(llvm::Function&) (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x82bd9c4)
# | #16 0x0000561e98892bf2 llvm::FPPassManager::runOnModule(llvm::Module&) (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x82c5bf2)
# | #17 0x0000561e9888b4e6 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x82be4e6)
# | #18 0x0000561e95c774e8 compileModule(char**, llvm::SmallVectorImpl<llvm::PassPlugin>&, llvm::LLVMContext&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) llc.cpp:0:0
# | #19 0x0000561e95c747a6 main (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x56a77a6)
# | #20 0x00007fdf20d76865 __libc_start_main (/lib64/libc.so.6+0x3a865)
# | #21 0x0000561e95c7392e _start (/repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/llc+0x56a692e)
# `-----------------------------
# error: command failed with exit status: -6
# executed command: /repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/FileCheck /repo/llvm-main-expensive-checks/llvm/test/CodeGen/AArch64/sve2-intrinsics-reinterpret.ll
# .---command stderr------------
# | FileCheck error: '<stdin>' is empty.
# | FileCheck command line: /repo/llvm-main-expensive-checks/llvm/build-all-expensive/bin/FileCheck /repo/llvm-main-expensive-checks/llvm/test/CodeGen/AArch64/sve2-intrinsics-reinterpret.ll
# `-----------------------------
# error: command failed with exit status: 2
```
https://github.com/llvm/llvm-project/pull/190139
More information about the llvm-commits
mailing list