This is an archive of the discontinued LLVM Phabricator instance.

[docs] Make it clear shifts yield poison when shift amount >= bitwidth
ClosedPublic

Authored by nlopes on May 29 2017, 11:59 AM.

Details

Summary

This should be NFC: it's just to make it clear in the docs that shift returns a poison value if shift amount >= bitwidth (and not an undef value).
A few instcombine optimizations rely on this already.

Diff Detail

Repository
rL LLVM

Event Timeline

nlopes created this revision.May 29 2017, 11:59 AM
nlopes retitled this revision from [docs] Make it clear shifts yield poison when shift ammount >= bitwidth to [docs] Make it clear shifts yield poison when shift amount >= bitwidth.
sanjoy edited edge metadata.May 29 2017, 8:07 PM

A few instcombine optimizations rely on this already.

Can you please give one or two examples?

This one for example (stole from Dave; I don't have my list here handy):
rewrite (1 << Y) * X into X << Y:

%Op0 = shl 1, %Y
%r = mul %Op0, %Op1

=>

%r = shl %Op1, %Y

With shl yielding undef this optimization is incorrect:

ERROR: Mismatch in values for i4 %r

Example:
i4 %Y = 0x8 (8, -8)
i4 %Op0 = 0x0 (0)
i4 %Op1 = 0x0 (0)
source: 0x0 (0)
target: 0x1 (1)

efriedma edited edge metadata.May 30 2017, 4:19 PM

Looking over LangRef, I think these are the operations which can return undef given operands that aren't undef/poison, and are likely reasonable to change over to return poison:

  1. sitofp and friends (if the result is out of range)
  2. llvm.ctlz.* and friends (is_zero_undef)
  3. shufflevector (undef elements in shuffle mask)
  4. shl and friends (shift amount out of range)
  5. alloca (allocating zero bytes)
  6. insertelement/extractelement (element index out of range)
  7. certain operations involving the result of an inrange GEP (see http://llvm.org/docs/LangRef.html#getelementptr-instruction)

If we're committing to killing undef, I think switching all of these to do something other than return undef is fine as an intermediate step... but please send a proposal to llvmdev outlining what's changing (or not really changing, as the case may be), and how it interacts with the general undef/poison/freeze plan.

(The other places I can find that say we return undef are loads and fast-math floating-point operations. Loads are obviously special, and the description of nnan/ninf should probably say it returns an unspecified value rather than undef.)

sanjoy accepted this revision.Jun 4 2017, 2:50 PM

This one for example (stole from Dave; I don't have my list here handy):

Thanks, can you please put this in the commit message? Other than that this LGTM, but I also agree with what Eli said.

rewrite (1 << Y) * X into X << Y:

%Op0 = shl 1, %Y
%r = mul %Op0, %Op1

=>

%r = shl %Op1, %Y

With shl yielding undef this optimization is incorrect:

ERROR: Mismatch in values for i4 %r

Example:
i4 %Y = 0x8 (8, -8)
i4 %Op0 = 0x0 (0)
i4 %Op1 = 0x0 (0)
source: 0x0 (0)
target: 0x1 (1)

This revision is now accepted and ready to land.Jun 4 2017, 2:50 PM
This revision was automatically updated to reflect the committed changes.