Immediates in intrinsics

I'm trying to add intrinsics for the Signal Processing Engine
(FPU/vector unit) on some PowerPC cores, but running into a problem.
Some of the instructions take an immediate operand, but I can't figure
out how to make the intrinsic use an immediate, it just wants to load
a register as an argument to the function. Is there any way in the
.td file to describe the intrinsic as taking an immediate, or do I
need to generate an intermediate instruction identifier?


The fact that the intrinsic takes an immediate is usually encoded as part of the isel pattern selection

For example from an x86 intrinsic/instruction:

def INT : Ii8<0xcd, RawFrm, (outs), (ins u8imm:$trap), “int\t$trap”,
[(int_x86_int imm:$trap)], IIC_INT>;

I’m slightly confused by your question though as you mention register which sort of implies you’re looking at PowerPC assembly. But you also mention a function, but the intrinsic should have been turned into instructions before assembly and there should be no function call.

To add to this: it is the "imm:$trap" in the selection pattern that does it (the "imm:" part of it, to be even more specific).


If it’s any easier Justin,

there are plenty of examples in the PPC back end already. Take for example int_ppc_vsx_xxinsertw.

Hi Craig,

Thanks for your reply. The instructions in question don't have an
associated pattern currently, I've been trying to do the pattern
matching in the intrinsic Pat<>, which may be the wrong way to go.
The output of the following test case:

declare <2 x i32> @llvm.ppc.spe.evaddiw ( <2 x i32>, i32 )
define <2 x i32> @test_int_ppc_spe_evaddiw ( <2 x i32> %A ) {
  %0 = tail call <2 x i32> @llvm.ppc.spe.evaddiw ( <2 x i32> %A, i32 1 )
  ret <2 x i32> %0

looks like:

test_int_ppc_spe_evaddiw: # @test_int_ppc_spe_evaddiw
# %bb.0: # %entry
        li 4, 1
        evaddiw 3, Assertion failed: (isImm() && "This is not an
immediate"), function getImm, file
/home/chmeee/llvm_git/llvm/include/llvm/MC/MCInst.h, line 77.

So the instruction is expecting an immediate, but r4 is getting loaded
with the constant I expected to be the immediate, so it's rejecting

After reading Nemanja's reply, I checked the int_ppc_vsx_xxinsertw and
discovered I was simply missing a 'imm:' conversion in the intrinsic
pattern. So my pattern was:

     def : Pat<(int_ppc_spe_evaddiw v2i32:$A, i32:$B), (EVADDIW $A, $B)>;

and I changed it to:

     def : Pat<(int_ppc_spe_evaddiw v2i32:$A, i32:$B), (EVADDIW $A, imm:$B)>;

Now this intrinsic works correctly.

- Justin