Special casing SIMD OR in AArch64


I would like to create a special case match pattern for OR instruction in AArch64 (Turn it into ADD). I am kind of new to table-gen and AArch64. It seems the first pattern with GPR32 works, but not the second pattern with SIMD registers.

def special_rule_for_or : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
return trueOrFalse(); // return true or false depending on a set of rules.

def : Pat<(special_rule_for_or GPR32:$src1, GPR32:$src2),
(ADDWrr GPR32:$src1, GPR32:$src2)>;

def : Pat<(special_rule_for_or (v16i8 FPR128:$src1), (v16i8 FPR128:$src2)),
(ADDWrr (v16i8 FPR128:$src1), (v16i8 FPR128:$src2))>;

This is the error I am seeing now.

Type set is empty for each HW mode:
possible type contradiction in the pattern below (use -print-records with llvm-tblgen to see all expanded records).
anonymous_9036: (ADDWrr:{ *:[i32] } FPR128:{ *:[] }:$src1, FPR128:{ *:[v16i8] }:$src2)
Generated from record:
anonymous_9036 { // Pattern Pat
dag PatternToMatch = (or_is_add (v16i8 FPR128:$src1), (v16i8 FPR128:$src2));
list ResultInstrs = [(ADDWrr (v16i8 FPR128:$src1), (v16i8 FPR128:$src2))];
list Predicates = [];
int AddedComplexity = 0;
Included from /usr/local/google/home/adriantong/opensource/llvm-project/llvm/lib/Target/AArch64/AArch64.td:538:
/usr/local/google/home/adriantong/opensource/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td:8229:1: error: Type set is empty for each HW mode in ‘anonymous_9036’

Thanks !

ADDWrr is a register+register word add instruction, i.e. GPR32+GPR32->GPR32, hence why TableGen says the types contradict when you use something else. You probably want something like ADDv16i8.

Though, what is the reason behind doing this? Normally OR are preferred over ADD (DAGCombiner will convert the latter to the former), and if you don’t want that it may be better implemented at a higher level than instruction selection (i.e. something like a target hook that tells DAGCombiner to instead convert OR to ADD).


I think ADDWrr is the scalar instruction. The pattern needs a different instruction name for the SIMD version of add. It might be ADDv16i8 but I don’t know for sure.