Hi,
We have recently encountered incorrect code generation issues and I think it is a SCEVExpander bug exposed by a recent patch to add nuw/nsw flags when generating code for SCEVMulExpr.
The test case IR looks like this-
%1 = load i16, i16* %arrayidx
%2 = and i16 %1, -32768
The SCEV form of %2 is this-
(-32768 * (%1 /u -32768))
It has both nsw/nuw flags. The signed range of the second operand of SCEVMulExpr (%1 /u -32768) is [0, 2). So it can be either 0 or 1.
But SCEVExpander uses shl to generate the multiply. The generated IR looks something like this-
%7 = lshr i16 %gepload, 15
%8 = shl nuw nsw i16 %7, 15
The issue is that %8 is later simplified to zero because according to langref it produces poison otherwise -
If the nuw keyword is present, then the shift produces a poison value if it shifts out any non-zero bits. If the nsw keyword is present, then the shift produces a poison value if it shifts out any bits that disagree with the resultant sign bit.
Is this a real bug or am I missing something?
Thanks,
Pankaj