Instruction selection: immediate operand is converted to register operand unexpectedly

I have written such code in td file:

def : Pat<(and (shiftop<srl> GPR:$rs1, uimm5:$iloc), uimm5:$ilen),                                                                                                                                   
                (EBI GPR:$rs1, uimm5:$ilen, uimm5:$iloc)>;

In hoping to convert such ll code:

 %1 = lshr i32 %rs1, 5                                                                                                                                                           
 %and = and i32 %1, 2 


ebi a0, a0, 2, 5

But what I got is like this:

   li  a1, 5                                                                                                                                                                          
   ebi a0, a0, 2, a1

i.e, an extra instruction is created to load ‘5’ into register.
What’s the problem in my code for td file?


With debugging, I found out that in instruction seletion stage, the ‘2’ is automatically converted to type ‘targetconst’, but ‘5’ is ‘const’ type.
So I convert ‘5’ from ‘const’ type to ‘targetconst’ in td file, then the issue is gone.
Not sure if this is the correct/best fix though.

The difference between Constant and TargetConstant is Constant is materialized in a register, and TargetConstants are not. You didn’t share you definitions for your uimm5, but how you defined it will change if it will fold into the result operand or not.