Home | History | Annotate | Download | only in LoopInterchange
      1 ; REQUIRES: asserts
      2 ; RUN: opt < %s -basicaa -loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \
      3 ; RUN:     -verify-dom-info -verify-loop-info -stats 2>&1 | FileCheck -check-prefix=STATS %s
      4 ; RUN: FileCheck --input-file=%t %s
      5 
      6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      7 target triple = "x86_64-unknown-linux-gnu"
      8 
      9 @A = common global [100 x [100 x i32]] zeroinitializer
     10 
     11 declare void @foo(i64 %a)
     12 declare void @bar(i64 %a) readnone
     13 
     14 ;;--------------------------------------Test case 01------------------------------------
     15 ;; Not safe to interchange, because the called function `foo` is not marked as
     16 ;; readnone, so it could introduce dependences.
     17 ;;
     18 ;;  for(int i=0;i<100;i++) {
     19 ;;    for(int j=1;j<100;j++) {
     20 ;;      foo(i);
     21 ;;      A[j][i] = A[j][i]+k;
     22 ;;    }
     23 ;; }
     24 
     25 ; CHECK: --- !Missed
     26 ; CHECK-NEXT: Pass:            loop-interchange
     27 ; CHECK-NEXT: Name:            CallInst
     28 ; CHECK-NEXT: Function:        interchange_01
     29 ; CHECK-NEXT: Args:
     30 ; CHECK-NEXT  - String:          Cannot interchange loops due to call instruction.
     31 
     32 define void @interchange_01(i32 %k) {
     33 entry:
     34   br label %for1.header
     35 
     36 for1.header:
     37   %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc10 ]
     38   br label %for2
     39 
     40 for2:
     41   %indvars.iv = phi i64 [ %indvars.iv.next, %for2 ], [ 1, %for1.header ]
     42   call void @foo(i64 %indvars.iv23)
     43   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
     44   %lv = load i32, i32* %arrayidx5
     45   %add = add nsw i32 %lv, %k
     46   store i32 %add, i32* %arrayidx5
     47   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
     48   %exitcond = icmp eq i64 %indvars.iv, 99
     49   br i1 %exitcond, label %for2.loopexit , label %for2
     50 
     51 for2.loopexit:
     52   br label %for1.inc10
     53 
     54 for1.inc10:
     55   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
     56   %exitcond26 = icmp eq i64 %indvars.iv23, 99
     57   br i1 %exitcond26, label %for1.loopexit, label %for1.header
     58 
     59 for1.loopexit:
     60   br label %exit
     61 
     62 exit:
     63   ret void
     64 }
     65 
     66 ;;--------------------------------------Test case 02------------------------------------
     67 ;; Safe to interchange, because the called function `bar` is marked as readnone,
     68 ;; so it cannot introduce dependences.
     69 ;;
     70 ;;  for(int i=0;i<100;i++) {
     71 ;;    for(int j=1;j<100;j++) {
     72 ;;      bar(i);
     73 ;;      A[j][i] = A[j][i]+k;
     74 ;;    }
     75 ;; }
     76 
     77 ; CHECK: --- !Passed
     78 ; CHECK-NEXT: Pass:            loop-interchange
     79 ; CHECK-NEXT: Name:            Interchanged
     80 ; CHECK-NEXT: Function:        interchange_02
     81 ; CHECK-NEXT: Args:
     82 ; CHECK-NEXT:   - String:          Loop interchanged with enclosing loop.
     83 ; CHECK-NEXT: ...
     84 
     85 define void @interchange_02(i32 %k) {
     86 entry:
     87   br label %for1.header
     88 
     89 for1.header:
     90   %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc10 ]
     91   br label %for2
     92 
     93 for2:
     94   %indvars.iv = phi i64 [ %indvars.iv.next, %for2 ], [ 1, %for1.header ]
     95   call void @bar(i64 %indvars.iv23)
     96   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
     97   %lv = load i32, i32* %arrayidx5
     98   %add = add nsw i32 %lv, %k
     99   store i32 %add, i32* %arrayidx5
    100   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    101   %exitcond = icmp eq i64 %indvars.iv, 99
    102   br i1 %exitcond, label %for2.loopexit , label %for2
    103 
    104 for2.loopexit:
    105   br label %for1.inc10
    106 
    107 for1.inc10:
    108   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
    109   %exitcond26 = icmp eq i64 %indvars.iv23, 99
    110   br i1 %exitcond26, label %for1.loopexit, label %for1.header
    111 
    112 for1.loopexit:
    113   br label %exit
    114 
    115 exit:
    116   ret void
    117 }
    118 
    119 ; Check stats, we interchanged 1 out of 2 loops.
    120 ; STATS: 1 loop-interchange - Number of loops interchanged
    121