How to prevent LLVM from undoing a custom lowering

My target has only logical shifts and lacks an arithmetic right shift instruction.
I have a custom LowerSRA function that rewrites SRA as SHL + SIGN_EXTEND
when the shift width is either constant 16 or 24. Unfortunately, I observe that a
later pass combines the SHL + SIGN_EXTEND back into SRA so we crash.

The idea I had for defeating this behavior is lower to a target-specific
version of SHL and/or SIGN_EXTEND, rather than using the generic ISD::SHL
and/or ISD::SIGN_EXTEND. Is that the recommended way to do it?

G

Hi Greg,

It would be better to teach dag combine and legalize that SRA can be illegal. Everything that creates SRA (after legalize) should check to make sure it is legal before doing so. Also, it would be nice to put the logic to legalize SRA → SHL + SEXT_IN_REG into legalize itself. It is conceivable that other targets will have illegal SRAs.

-Chris