[LLVMdev] Cast to SCEVAddRecExpr

Sanjoy Das sanjoy at playingwithpointers.com
Mon Mar 30 21:10:55 PDT 2015


On Mon, Mar 30, 2015 at 8:47 PM, Nema, Ashutosh <Ashutosh.Nema at amd.com> wrote:
> Sorry typo in test case, Please ignore previous mail.
>
> Consider below case:
>
> for (j=1; j < itr; j++) {
>      - - - -
>      for (i=1; i < itr; i++) {
>      {
>        temp=  var[i << 1];
>         - - - - -
>      }
> }
>
> In the above example, we are unable to get "SCEVAddRecExpr" for "var[i  << 1]"

To be pedantic, "var[i<<1]" is not an add recurrence, but "&var[i <<
1]" is an add recurrence.  I'll assume that's that you meant.

If I run the following example through opt -analyze -scalar-evolution:

define void @x(i1* %c, i64* %ptr) {
 entry:
  br label %loop

 loop:
  %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ]
  %i.inc = add i64 %i, 1
  %d = shl i64 %i.inc, 1
  %gep = getelementptr i64, i64* %ptr, i64 %d
  %cc = load volatile i1, i1* %c
  br i1 %cc, label %exit, label %loop

 exit:
  ret void
}


I get the SCEV -->  {(16 + %ptr),+,16}<%loop> for %gep.  So SCEV /can/
interpret i<<1 as i*2 under some specific circumstances.

Going back to your original question:

> Instead if I change "var[i << 1]" to "var[i * 2]" then I'm getting "SCEVAddRecExpr".

I think that is because in C, multiplication is nsw but left shift is
not and so "i << 1" can legitimately sign-overflow but i * 2 cannot
sign-overflow.  I'd venture a guess that this lets LLVM transform a
sign-extend of an add-rec to an add-rec sign-extends.

Caveat: I have not looked at the C specification to determine that
left shifts are allowed to sign-overflow.  I concluded that left
shifts are not nsw by looking at the llvm IR emitted by clang (the
left shift generated from "i << 1" is not marked nsw).

-- Sanjoy



More information about the llvm-dev mailing list