[PATCH] D48853: [SCEV] Add [zs]ext{C, +, x} -> (D + [zs]ext{C-D, +, x})<nuw><nsw> transform

Roman Tereshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 19 17:38:34 PDT 2018


rtereshin updated this revision to Diff 156411.
rtereshin added a comment.

Updated and added comments as requested, renamed `FullExpr` to `WholeAddExpr`, and planned to add the following piece to the end of the commit message:

  How it all works:
  
  Let say we have an AddExpr that looks like (C + x + y + ...), where C
  is a constant and x, y, ... are arbitrary SCEVs. Let's compute the
  minimum number of trailing zeroes guaranteed of that sum w/o the
  constant term: (x + y + ...). If, for example, those terms look like
  follows:
  
          i
  XXXX...X000
  YYYY...YY00
     ...
  ZZZZ...0000
  
  then the rightmost non-guaranteed-zero bit (a potential one at i-th
  position above) can change the bits of the sum to the left (and at
  i-th position itself), but it can not possibly change the bits to the
  right. So we can compute the number of trailing zeroes by taking a
  minimum between the numbers of trailing zeroes of the terms.
  
  Now let's say that our original sum with the constant is effectively
  just C + X, where X = x + y + .... Let's also say that we've got 2
  guaranteed trailing zeros for X:
  
          j
  CCCC...CCCC
  XXXX...XX00  // this is X = (x + y + ...)
  
  Any bit of C to the left of j may in the end cause the C + X sum to
  wrap, but the rightmost 2 bits of C (at positions j and j - 1) do not
  affect wrapping in any way. If the upper bits cause a wrap, it will be
  a wrap regardless of the values of the 2 least significant bits of C.
  If the upper bits do not cause a wrap, it won't be a wrap regardless
  of the values of the 2 bits on the right (again).
  
  So let's split C to 2 constants like follows:
  
  0000...00CC  = D
  CCCC...CC00  = (C - D)
  
  and represent the whole sum as D + (C - D + X). The second term of
  this new sum looks like this:
  
  CCCC...CC00
  XXXX...XX00
  -----------  // let's add them up
  YYYY...YY00
  
  The sum above (let's call it Y)) may or may not wrap, we don't know,
  so we need to keep it under a sext/zext. Adding D to that sum though
  will never wrap, signed or unsigned, if performed on the original bit
  width or the extended one, because all that that final add does is
  setting the 2 least significant bits of Y to the bits of D:
  
  YYYY...YY00 = Y
  0000...00CC = D
  -----------  <nuw><nsw>
  YYYY...YYCC
  
  Which means we can safely move that D out of the sext or zext and
  claim that the top-level sum neither sign wraps nor unsigned wraps.
  
  Let's run an example, let's say we're working in i8's and the original
  expression (zext's or sext's operand) is 21 + 12x + 8y. So it goes
  like this:
  
  0001 0101  // 21
  XXXX XX00  // 12x
  YYYY Y000  // 8y
  
  0001 0101  // 21
  ZZZZ ZZ00  // 12x + 8y
  
  0000 0001  // D
  0001 0100  // 21 - D = 20
  ZZZZ ZZ00  // 12x + 8y
  
  0000 0001  // D
  WWWW WW00  // 21 - D + 12x + 8y = 20 + 12x + 8y
  
  therefore zext(21 + 12x + 8y) = (1 + zext(20 + 12x + 8y))<nuw><nsw>


Repository:
  rL LLVM

https://reviews.llvm.org/D48853

Files:
  lib/Analysis/ScalarEvolution.cpp
  test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll
  test/Transforms/IndVarSimplify/shrunk-constant.ll
  test/Transforms/LoadStoreVectorizer/X86/codegenprepare-produced-address-math.ll
  test/Transforms/SLPVectorizer/X86/consecutive-access.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48853.156411.patch
Type: text/x-patch
Size: 24597 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180720/ad68ceef/attachment.bin>


More information about the llvm-commits mailing list