[LLVMdev] bitconvert for multi-typed RegisterClasses

Christopher Lamb christopher.lamb at gmail.com
Mon Feb 12 11:56:16 PST 2007


On Feb 12, 2007, at 12:58 PM, Evan Cheng wrote:

>
> On Feb 12, 2007, at 1:41 AM, Christopher Lamb wrote:
>
>>
>> selector refused to select certain ops (specifically stores) for some
>> instructions when the operand type wasn't the first type for the
>> register class. After some digging around I seem to have solved the
>> problem by creating bitconvert patterns between the types in the
>> register class like the following:
>>
>> def : Pat<(type1 (bitconvert (type2 MR:$src))), (type1 MR:$src)>;
>> def : Pat<(type2 (bitconvert (type1 MR:$src))), (type2 MR:$src)>;
>> ...
>>
>> Adding these patterns appeared to allow the instruction selector to
>> select/legalize the store operations. So I have two questions:
>>
>> 1) Is relying on these patterns for instruction selection/
>> legalization the correct way to implement multi-typed
>> RegisterClasses? I like having TableGen do the pattern work for me
>> rather than writing custom selection code...
>>
>> 2) I'd think that when a multi-typed RegisterClass is declared that
>> these bitconvert patterns between types in that class automatically
>> become legal. Is there a reason that TableGen shouldn't automatically
>> generate these patterns when a multi-typed register class is created?
>
> X86 backend has the VR64 and VR128 register classes which are exactly
> like this. Rather than adding a whole bunch of instruction selection
> rules to match all the possibilities. We've decided to ask the
> legalizer to normalize the target-independent nodes to one particular
> type. See X86ISelLowering.cpp:
>
>      // Promote v16i8, v8i16, v4i32 load, select, and, or, xor to  
> v2i64.
>      for (unsigned VT = (unsigned)MVT::v16i8; VT != (unsigned)
> MVT::v2i64; VT++) {
>        setOperationAction(ISD::AND,    (MVT::ValueType)VT, Promote);
>        AddPromotedToType (ISD::AND,    (MVT::ValueType)VT,  
> MVT::v2i64);
>       ...
>
> Evan

Thanks Evan,

I had tried something like this, but ran into some problems.

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1478: failed assertion  
`MVT::isVector(VT) && "Cannot promote this load!"'

and

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1766: failed assertion  
`MVT::isVector(VT) && "Unknown legal promote case!"'


it appears that for load/store only vector types of equivalent bit- 
widths can be promoted in this way, but one cannot promote an f32 to  
an i32.

Also, I was incorrect in thinking that the bitconvert patterns I  
mentioned in the original post had solved my problems. I ended up  
having to explicitly add patterns for the f32 types to the  
InstrInfo.td. And then, it only seems to work if I add a pseudo  
instruction with the following selection pattern (store (f32 Regs: 
$src), ADDRri:$addr), rather than adding a pattern such as the  
following:

def : Pat<(store (f32 Regs:$src), ADDRri:$addr), (ST32 Regs:$src,  
ADDRri:$addr)>;

The above pattern produced the following error because the  
TargetOperandInfo for the 1 operand of the store had a NULL register  
class.

llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:304: failed assertion  
`RC && "Don't have operand info for this instruction!"'

Why the pseudo-op doesn't have this problem, I'm not clear.

Thanks
--
Christopher Lamb

>
>>
>> Thanks
>> --
>> Christopher Lamb
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list