How to extend LLVM Intrinsic

Hey everyone,

Recently I’m trying to extend an LLVM intrinsic, more precisely, add a default argument for the function, but I don’t how to get there.

The first problem I ran into is that can we have a default argument for the LLVM intrinsic? or I should overload it to have another argument?

I tried to follow ExtendingLLVM, but I got confused a little bit. First I changed the declaration of the intrinsic in llvm-project/llvm/include/llvm/IR/Intrinsics.td, and then implemented the feature in llvm-project/llvm/lib/CodeGen/ExpandReductions.cpp.

The docs says:

Add support to the .td file for the target(s) of your choice in lib/Target/*/*.td

But the problem is that I can’t even find the intrinsic in some targets! :frowning:
I tried to use grep to them, but the only relevant code looks like:

let Predicates = [HasFullFP16] in {
def : Pat<(f16 (vecreduce_fadd (v8f16 V128:$Rn))),
            (FADDPv2i16p
              (EXTRACT_SUBREG
                 (FADDPv8f16 (FADDPv8f16 V128:$Rn, (v8f16 (IMPLICIT_DEF))), (v8f16 (IMPLICIT_DEF))),
               dsub))>;
def : Pat<(f16 (vecreduce_fadd (v4f16 V64:$Rn))),
          (FADDPv2i16p (FADDPv4f16 V64:$Rn, (v4f16 (IMPLICIT_DEF))))>;
}
def : Pat<(f32 (vecreduce_fadd (v4f32 V128:$Rn))),
          (FADDPv2i32p
            (EXTRACT_SUBREG
              (FADDPv4f32 V128:$Rn, (v4f32 (IMPLICIT_DEF))),
             dsub))>;
def : Pat<(f32 (vecreduce_fadd (v2f32 V64:$Rn))),
          (FADDPv2i32p V64:$Rn)>;
def : Pat<(f64 (vecreduce_fadd (v2f64 V128:$Rn))),
          (FADDPv2i64p V128:$Rn)>;

I have no idea about what’s going on there…

I think the main issue about myself is that I don’t have a good understanding of the IR, can anyone give me some hints about how to do it? Thanks a lot!

It’s probably best to add a new argument to the existing intrinsic and then update the auto-upgrader to add the new argument (llvm/lib/IR/AutoUpgrade.cpp)

That sounds like it should be enough for an initial patch.

The way the reduction intrinsics work is that by default, targets do not have to implement lowering the reductions directly. In that case, ExpandReductions.cpp is responsible for remove them before they reach instruction selection. Only certain targets, like AArch64, lower the intrinsics directly in the backend. Only those need to be updated.

1 Like