Skip to content

[TableGen][GISel] Incorrect handling of ignored ComplexPattern with GISelPredicateCode + PredicateCodeUsesOperands = 1 #68166

Open
@mshockwave

Description

@mshockwave

Here is the code that triggers this issue (please paste boilerplate code from test/TableGen/GlobalISelEmitterCustomPredicate.td at the beginning of this file). Also, this bug follows up the patch presented in #68125.

def DOP : RegisterOperand<DRegs>;
def MUL_OR : I<(outs DRegs:$dst), (ins DOP:$src0, DOP:$src1, DOP:$src2), []>;

def or_complex_pattern : ComplexPattern<i32, 2, "selectOrComplex">;

def mul_pat : PatFrag<
  (ops node:$x, node:$y),
  (mul node:$x, node:$y), [{ ... }]> {
  let GISelPredicateCode = [{ ... }];
  let PredicateCodeUsesOperands = 1;
}

def : Pat<
  (i32 (mul_pat (or_complex_pattern DOP:$src0, DOP:$src1), DOP:$src2)),
  (MUL_OR DOP:$src0, DOP:$src1, DOP:$src2)
>;

When running with -gen-global-isel, llvm-tblgen cashes with the following message:

llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp:775: Expected<llvm::gi::InstructionMatcher &> (anonymous namespace)::GlobalISelEmitter::createAndImportSelDAGMatcher(llvm::gi::RuleMatcher &, llvm::gi::InstructionMatcher &, const llvm::TreePatternNode *, unsigned int &): Assertion `WaitingForNamedOperands == 0 && "previous predicate didn't find all operands or " "nested predicate that uses operands"' failed.

Here is the root cause: WaitingForNamedOperands is a counter that keeps tracks of operand mapping while using GISelPredicateCode + PredicateCodeUsesOperands = 1. It's subtracted by one for each PatFrag operand and it should be zero, namely the assertion message, before we start processing another PatFrag.
For instance, when processing (mul_pat (or_complex_pattern DOP:$src0, DOP:$src1), DOP:$src2), WaitingForNamedOperands is initialized with 2, the number of PatFrag operands. It is subtracted by 1 after (or_complex_pattern DOP:$src0, DOP:$src1) is handled, but since or_complex_pattern has no GISel counterpart, GlobalISelEmitter bails out (too) early and skips DOP:$src2 entirely, leaving WaitingForNamedOperands a non-zero value, hence the assertion failure.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions