Confuse on getSCEVAtScope

hi all,

i have SCEVAddRec

{{(32 + @edge.8265),+,32}<Loop0>,+,4}<Loop1>

where Loop0 and Loop1 are brothers (loops at the same level of the
loopnest), and Loop0 have a computable backedge taken count.

when i call getSCEVAtScope({{(32 +
@edge.8265),+,32}<Loop0>,+,4}<Loop1> , Loop1), it just give me a
{{(32 + @edge.8265),+,32}<Loop0>,+,4}<Loop1>,
instead of {some_value, + ,4}<loop0>, where some_value is
getSCEVAtScope({(32 + @edge.8265),+,32}<Loop0>, Loop1). because Loop0
have a computable backedge taken count, some_value should not be a
SCEVAddRec.

and later i have a look computeSCEVAtScope, and see the function do
not do any thing when AddRec->getLoop()->contains(L).
why computeSCEVAtScope not try to get the operands in the current
scope like the function do with SCEVCommutativeExpr, like:

if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
    if (!L || !AddRec->getLoop()->contains(L)) {
      ...
      // Then, evaluate the AddRec.
      AddRec = AddRec->evaluateAtIteration(BackedgeTakenCount, *this);
    }

    try to evalue every operand of AddRec;

    return AddRec;
  }

thanks very much.

That looks reasonable to me. Do you have a testcase which exhibits this?

Dan

hi,

i see some improvement on this :slight_smile:
and the testcase is (maybe too late):
; ModuleID = '/home/ether/where_comes_the_indvar.bc'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"

@edge.8265 = external global [72 x i32], align 32 ; <[72 x i32]*> [#uses=1]

define void @compact_unitcell_edges() nounwind {
bb.nph19:
  br label %bb4

bb4: ; preds = %bb4, %bb.nph19
  %e.118 = phi i32 [ 0, %bb.nph19 ], [ %tmp23, %bb4 ] ; <i32> [#uses=1]
  %i.017 = phi i32 [ 0, %bb.nph19 ], [ %0, %bb4 ] ; <i32> [#uses=1]
  %tmp23 = add i32 %e.118, 8 ; <i32> [#uses=2]
  %0 = add nsw i32 %i.017, 1 ; <i32> [#uses=2]
  %exitcond42 = icmp eq i32 %0, 6 ; <i1> [#uses=1]
  br i1 %exitcond42, label %bb.nph, label %bb4

bb.nph: ; preds = %bb4
  %tmp = sext i32 %tmp23 to i64 ; <i64> [#uses=1]
  br label %bb7

bb7: ; preds = %bb7, %bb.nph
  %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb7 ] ; <i64> [#uses=2]
  %tmp21 = add i64 %tmp, %indvar ; <i64> [#uses=1]
  %scevgep = getelementptr [72 x i32]* @edge.8265, i64 0, i64 %tmp21 ;
<i32*> [#uses=1]
  store i32 undef, i32* %scevgep, align 4
  %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
  br i1 undef, label %bb10, label %bb7

bb10: ; preds = %bb7
  ret void
}

which get

$ bin/opt -scalar-evolution -analyze ~/where_comes_the_indvar.ll
Printing analysis 'Scalar Evolution Analysis' for function
'compact_unitcell_edges':
Classifying expressions for: @compact_unitcell_edges
  %e.118 = phi i32 [ 0, %bb.nph19 ], [ %tmp23, %bb4 ] ; <i32> [#uses=1]
  --> {0,+,8}<%bb4> Exits: 40
  %i.017 = phi i32 [ 0, %bb.nph19 ], [ %0, %bb4 ] ; <i32> [#uses=1]
  --> {0,+,1}<%bb4> Exits: 5
  %tmp23 = add i32 %e.118, 8 ; <i32> [#uses=2]
  --> {8,+,8}<%bb4> Exits: 48
  %0 = add nsw i32 %i.017, 1 ; <i32> [#uses=2]
  --> {1,+,1}<%bb4> Exits: 6
  %tmp = sext i32 %tmp23 to i64 ; <i64> [#uses=1]
  --> {8,+,8}<%bb4> --> 48
  %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb7 ] ; <i64> [#uses=2]
  --> {0,+,1}<%bb7> Exits: <<Unknown>>
  %tmp21 = add i64 %tmp, %indvar ; <i64> [#uses=1]
  --> {{8,+,8}<%bb4>,+,1}<%bb7>
<------------------------------------------------------------------------------------
the start could be evaluate
  %scevgep = getelementptr [72 x i32]* @edge.8265, i64 0, i64 %tmp21 ;
<i32*> [#uses=1]
  --> {{(32 + @edge.8265),+,32}<%bb4>,+,4}<%bb7>
<-------------------------------------------------- the start could
be evaluate
  %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
  --> {1,+,1}<%bb7> Exits: <<Unknown>>