Why ISel Shifts operations can only be expanded for Value type vector ?

Hello LLVM Devs,

I am working on a target on which no SHL instruction is available. So wanted to expand it through MUL. But currently it is only possible to expand SHL for vector types.

One possible reason I can think is because LLVM tries to optimize MUL to SHL in certain cases and that can make compiler co in loop or may end up generating wrong code.

But I think SHL should be able to expanded to MUL and to prevent looping between MUL and SHL we can put a condition that only optimize MUL to SHL when SHL is not expanded operation. The similar logic can be applied to DIV and SRA.

If there is any other reasons for not doing this, kindly explain.

Sincerely,
Vivek

There isn't anything fundamental; it just hasn't come up for any in-tree target.

-Eli

Why you can’t still expand it through MUL with a Custom lowering? Or am I missing something?

Thanks.

Why you can’t still expand it through MUL with a Custom lowering? Or am I missing something?

Yes we can but problem occurs when we know that it is shift with constant value than if we return ISD::MUL with constant imm operand than LLVM will convert it to SHL again because the constant will be power of 2. Thus it creates loop.
So we may add target specific ISD node and lower it to mul instruction.

–Vivek

If your target does not have SHL then why don’t you simply disable converting MUL to SHL?

If your target does not have SHL then why don't you simply disable
converting MUL to SHL?

MUL is converted to SHL by target independent passes when second operand

is power of 2.

-Vivek

So then just generate assembly code for SHL as a MUL…

So then just generate assembly code for SHL as a MUL...

Yes that is what I have done currently but if any new architectures

(specially which are having low capability) may want similar behavior then
we can just make LLVM expand SHL with MUL.
Also when shift amount is not a constant then it need to lower it to loop
that can multiply value to 2^k (i.e generating first 2^k ) if this is
common case then we can just update LLVM to do this.
Similar things applies to divide and SAR pair.

-Vivek

Which target independent passes do you mean that are doing this in DAG?

Which target independent passes do you mean that are doing this in DAG?

For example

https://github.com/llvm-mirror/llvm/blob/master/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp#L3320

-Vivek

To be clear, where r u trying to lower it? Naturally this should happen in XXXISelLowering.

Again to be clear, you r calling a custom hook and not using expand correct?

Yes I have custom hook for both mul and shifts because if barrel shift hardware unit is present than we try to optmize MUL to SHL. and if barrel shiftier is not present than hardware can use MUL and ADD to implement left shift operation.

  • Vivek