[llvm-dev] SCEVExpander bug?

Eli Friedman via llvm-dev llvm-dev at lists.llvm.org
Tue Jun 25 14:06:17 PDT 2019


Real bug; the shift shouldn't be marked nsw.  (See also https://github.com/llvm/llvm-project/blob/5e13cd2e61cb187f28d743c15141333530cc1adf/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp#L177 .)

-Eli

From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Chawla, Pankaj via llvm-dev
Sent: Tuesday, June 25, 2019 1:39 PM
To: llvm-dev at lists.llvm.org
Cc: Bakhvalov, Denis <denis.bakhvalov at intel.com>
Subject: [EXT] [llvm-dev] SCEVExpander bug?

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))<nuw><nsw>

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190625/969f4c63/attachment.html>


More information about the llvm-dev mailing list