[llvm] [GlobalISel] Combine (X == 0) & (Y == 0) -> (X | Y) == 0 (PR #69017)

Dávid Ferenc Szabó via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 22 02:21:18 PDT 2023


dfszabo wrote:

> > > Can you try doing this with the new tablegen combiner support?
> > 
> > 
> > Good idea, but for the reason @aemerson mentioned it does not seem feasible.
> 
> You can mix MIR patterns and C++. You can do most of the matching with MIR patterns, have an "out" pattern as well, and just use a smaller C++ function to verify the more complex matching predicates. You'd need two rules though, one for AND and one for OR, since the output inst is different for each. Also I'm not sure how ICMP works yet with MIR patterns, I'll need to take a look at that.
> 
> Can you try that approach and if it proves impossible or just too annoying, let me know your thoughts? It'd help a lot :)

I tried this approach and I think I nailed it but the tests are crashing. Any idea?
```
// Transform: (X == 0 & Y == 0) -> (X | Y) == 0
def double_icmp_zero_and_combine: GICombineRule<
  (defs root:$root),
  (match (G_ICMP $d1, $p, $s1, 0),
         (G_ICMP $d2, $p, $s2, 0),
         (G_AND $root, $d1, $d2),
         [{ return ${p}.getPredicate() == CmpInst::ICMP_EQ &&
                       !MRI.getType(${s1}.getReg()).isPointer() &&
                       MRI.getType(${s1}.getReg()) ==
                           MRI.getType(${s2}.getReg()); }]),
  (apply (G_OR i1:$ordst, $s1, $s2),
         (G_ICMP $root, $p, $ordst, 0))
>;

// Transform: (X != 0 | Y != 0) -> (X | Y) != 0
def double_icmp_zero_or_combine: GICombineRule<
  (defs root:$root),
  (match (G_ICMP $d1, $p, $s1, 0),
         (G_ICMP $d2, $p, $s2, 0),
         (G_OR $root, $d1, $d2),
         [{ return ${p}.getPredicate() == CmpInst::ICMP_NE &&
                       !MRI.getType(${s1}.getReg()).isPointer() &&
                       MRI.getType(${s1}.getReg()) ==
                           MRI.getType(${s2}.getReg()); }]),
  (apply (G_OR i1:$ordst, $s1, $s2),
         (G_ICMP $root, $p, $ordst, 0))
>;

def double_icmp_zero_and_or_combine : GICombineGroup<[double_icmp_zero_and_combine,
                                                      double_icmp_zero_or_combine]>;
```
```
 #0 0x00007f3028ed17b2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/david/work/llvm-community/llvm-project/llvm/lib/Support/Unix/Signals.inc:723:22
 #1 0x00007f3028ed1bc3 PrintStackTraceSignalHandler(void*) /home/david/work/llvm-community/llvm-project/llvm/lib/Support/Unix/Signals.inc:798:1
 #2 0x00007f3028ecf146 llvm::sys::RunSignalHandlers() /home/david/work/llvm-community/llvm-project/llvm/lib/Support/Signals.cpp:105:20
 #3 0x00007f3028ed106c SignalHandler(int) /home/david/work/llvm-community/llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1
 #4 0x00007f30286b50c0 (/lib/x86_64-linux-gnu/libc.so.6+0x430c0)
 #5 0x00007f303030765a llvm::MachineBasicBlock::getParent() /home/david/work/llvm-community/llvm-project/llvm/include/llvm/CodeGen/MachineBasicBlock.h:275:41
 #6 0x00007f30303551cc llvm::BuildMI(llvm::MachineBasicBlock&, llvm::MachineInstrBundleIterator<llvm::MachineInstr, false>, llvm::MIMetadata const&, llvm::MCInstrDesc const&) /home/david/work/llvm-community/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBuilder.h:435:38
 #7 0x00007f30303553fe llvm::BuildMI(llvm::MachineBasicBlock&, llvm::MachineInstr&, llvm::MIMetadata const&, llvm::MCInstrDesc const&) /home/david/work/llvm-community/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBuilder.h:459:1
 #8 0x00007f3030355448 llvm::BuildMI(llvm::MachineBasicBlock&, llvm::MachineInstr*, llvm::MIMetadata const&, llvm::MCInstrDesc const&) /home/david/work/llvm-community/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBuilder.h:465:1
 #9 0x00007f30303b439d bool llvm::GIMatchTableExecutor::executeMatchTable<(anonymous namespace)::AArch64PreLegalizerCombinerImpl const, llvm::Bitset<0u>, std::optional<llvm::SmallVector<std::function<void (llvm::MachineInstrBuilder&)>, 4u>> ((anonymous namespace)::AArch64PreLegalizerCombinerImpl::*)(llvm::MachineOperand&) const, void ((anonymous namespace)::AArch64PreLegalizerCombinerImpl::*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&, int) const>((anonymous namespace)::AArch64PreLegalizerCombinerImpl const&, llvm::SmallVector<llvm::MachineInstrBuilder, 4u>&, llvm::GIMatchTableExecutor::MatcherState&, llvm::GIMatchTableExecutor::ExecInfoTy<llvm::Bitset<0u>, std::optional<llvm::SmallVector<std::function<void (llvm::MachineInstrBuilder&)>, 4u>> ((anonymous namespace)::AArch64PreLegalizerCombinerImpl::*)(llvm::MachineOperand&) const, void ((anonymous namespace)::AArch64PreLegalizerCombinerImpl::*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&, int) const> const&, long const*, llvm::TargetInstrInfo const&, llvm::MachineRegisterInfo&, llvm::TargetRegisterInfo const&, llvm::RegisterBankInfo const&, llvm::Bitset<0u> const&, llvm::CodeGenCoverage*, llvm::GISelChangeObserver*) const /home/david/work/llvm-community/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h:917:34
#10 0x00007f30303ac6eb (anonymous namespace)::AArch64PreLegalizerCombinerImpl::tryCombineAllImpl(llvm::MachineInstr&) const /home/david/work/llvm-community/build/lib/Target/AArch64/AArch64GenPreLegalizeGICombiner.inc:1699:24
#11 0x00007f30303ada13 (anonymous namespace)::AArch64PreLegalizerCombinerImpl::tryCombineAll(llvm::MachineInstr&) const /home/david/work/llvm-community/llvm-project/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp:392:3
#12 0x00007f3028167bb8 llvm::Combiner::combineMachineInstrs() /home/david/work/llvm-community/llvm-project/llvm/lib/CodeGen/GlobalISel/Combiner.cpp:165:15
#13 0x00007f30303adfea (anonymous namespace)::AArch64PreLegalizerCombiner::runOnMachineFunction(llvm::MachineFunction&) /home/david/work/llvm-community/llvm-project/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp:490:35
#14 0x00007f302d7ce366 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) /home/david/work/llvm-community/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:93:33

```
Seems like the BB's parent is nullptr, don't know why though.

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


More information about the llvm-commits mailing list