Thanks Sanjay!
I did a quick study of these funnel shifts:
The generic lowering to SDAG is correct for the optimization below. It actually stops poison if shift amount is zero:
SDValue ShAmt = DAG.getNode(ISD::UREM, sdl, VT, Z, BitWidthC);
(...)
SDValue IsZeroShift = DAG.getSetCC(sdl, CCVT, ShAmt, Zero, ISD::SETEQ);
setValue(&I, DAG.getSelect(sdl, VT, IsZeroShift, IsFSHL ? X : Y, Or));
This is assuming select in SDAG stops poison in the same way we've proposed for the IR.
However, the lowering has 2 optimizations. It can lower funnel shifts to:
1) A special funnel shift instruction if the backend supports it
2) Rotate
At least lowering to rotate would be incorrect if rotate didn't stop poison as well when shift amount == 0. Most likely rotate doesn't block poison though. So this doesn't seem correct.
Blocking poison, while tempting, is usually not a good idea because it blocks many optimizations. It becomes hard to remove instructions that block poison. Exactly as you see here: if select blocks poison (and we claim it does), then it cannot be removed.
I have 2 separate proposals:
1) Keep select blocking poison, and remove the transformation below because it doesn't play well with 1) lowering to rotate, and 2) because it blocks optimizations like converting funnel shifts to plain shifts
2) Introduce a flag in select, like we have nsw/nuw today that changes the semantics regarding poison. Essentially a select that doesn't stop poison. This can be safely emitted by most frontends of the languages we support today, but wouldn't be used by compiler-introduced selects. The optimization below would only kick in when this flag is present. Of course then we can have an analysis that inserts these flags like we have for nsw.
I like 2), but 1) is simpler. I don't know if 2) is worth it, but is appealing 
Nuno