1; Test optimization remarks generated by the LoopInterchange pass. 2; 3; RUN: opt < %s -basic-aa -loop-interchange -verify-dom-info -verify-loop-info \ 4; RUN: -pass-remarks-output=%t -pass-remarks-missed='loop-interchange' \ 5; RUN: -pass-remarks='loop-interchange' -S 6; RUN: cat %t | FileCheck %s 7 8; RUN: opt < %s -basic-aa -loop-interchange -verify-dom-info -verify-loop-info \ 9; RUN: -pass-remarks-output=%t -pass-remarks-missed='loop-interchange' \ 10; RUN: -pass-remarks='loop-interchange' -S -da-disable-delinearization-checks 11; RUN: cat %t | FileCheck --check-prefix=DELIN %s 12 13@A = common global [100 x [100 x i32]] zeroinitializer 14@B = common global [100 x [100 x i32]] zeroinitializer 15@C = common global [100 x i32] zeroinitializer 16 17;;---------------------------------------Test case 01--------------------------------- 18;; Loops interchange is not profitable. 19;; for(int i=1;i<N;i++) 20;; for(int j=1;j<N;j++) 21;; A[i-1][j-1] = A[i - 1][j-1] + B[i][j]; 22 23define void @test01(i32 %N){ 24entry: 25 %cmp31 = icmp sgt i32 %N, 1 26 br i1 %cmp31, label %for.cond1.preheader.lr.ph, label %for.end19 27 28for.cond1.preheader.lr.ph: 29 %0 = add i32 %N, -1 30 br label %for.body3.lr.ph 31 32for.body3.lr.ph: 33 %indvars.iv34 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next35, %for.inc17 ] 34 %1 = add nsw i64 %indvars.iv34, -1 35 br label %for.body3 36 37for.body3: 38 %indvars.iv = phi i64 [ 1, %for.body3.lr.ph ], [ %indvars.iv.next, %for.body3 ] 39 %2 = add nsw i64 %indvars.iv, -1 40 %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %2 41 %3 = load i32, i32* %arrayidx6 42 %arrayidx10 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv34, i64 %indvars.iv 43 %4 = load i32, i32* %arrayidx10 44 %add = add nsw i32 %4, %3 45 store i32 %add, i32* %arrayidx6 46 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 47 %lftr.wideiv = trunc i64 %indvars.iv to i32 48 %exitcond = icmp eq i32 %lftr.wideiv, %0 49 br i1 %exitcond, label %for.inc17, label %for.body3 50 51for.inc17: 52 %indvars.iv.next35 = add nuw nsw i64 %indvars.iv34, 1 53 %lftr.wideiv37 = trunc i64 %indvars.iv34 to i32 54 %exitcond38 = icmp eq i32 %lftr.wideiv37, %0 55 br i1 %exitcond38, label %for.end19, label %for.body3.lr.ph 56 57for.end19: 58 ret void 59} 60 61; CHECK: --- !Missed 62; CHECK-NEXT: Pass: loop-interchange 63; CHECK-NEXT: Name: Dependence 64; CHECK-NEXT: Function: test01 65; CHECK-NEXT: Args: 66; CHECK-NEXT: - String: Cannot interchange loops due to dependences. 67; CHECK-NEXT: ... 68 69; DELIN: --- !Missed 70; DELIN-NEXT: Pass: loop-interchange 71; DELIN-NEXT: Name: InterchangeNotProfitable 72; DELIN-NEXT: Function: test01 73; DELIN-NEXT: Args: 74; DELIN-NEXT: - String: 'Interchanging loops is too costly (cost=' 75; DELIN-NEXT: - Cost: '2' 76; DELIN-NEXT: - String: ', threshold=' 77; DELIN-NEXT: - Threshold: '0' 78; DELIN-NEXT: - String: ') and it does not improve parallelism.' 79; DELIN-NEXT: ... 80 81;;--------------------------------------Test case 02------------------------------------ 82;; [FIXME] This loop though valid is currently not interchanged due to the 83;; limitation that we cannot split the inner loop latch due to multiple use of inner induction 84;; variable.(used to increment the loop counter and to access A[j+1][i+1] 85;; for(int i=0;i<N-1;i++) 86;; for(int j=1;j<N-1;j++) 87;; A[j+1][i+1] = A[j+1][i+1] + k; 88 89define void @test02(i32 %k, i32 %N) { 90 entry: 91 %sub = add nsw i32 %N, -1 92 %cmp26 = icmp sgt i32 %N, 1 93 br i1 %cmp26, label %for.cond1.preheader.lr.ph, label %for.end17 94 95 for.cond1.preheader.lr.ph: 96 %cmp324 = icmp sgt i32 %sub, 1 97 %0 = add i32 %N, -2 98 %1 = sext i32 %sub to i64 99 br label %for.cond1.preheader 100 101 for.cond.loopexit: 102 %cmp = icmp slt i64 %indvars.iv.next29, %1 103 br i1 %cmp, label %for.cond1.preheader, label %for.end17 104 105 for.cond1.preheader: 106 %indvars.iv28 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next29, %for.cond.loopexit ] 107 %indvars.iv.next29 = add nuw nsw i64 %indvars.iv28, 1 108 br i1 %cmp324, label %for.body4, label %for.cond.loopexit 109 110 for.body4: 111 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body4 ], [ 1, %for.cond1.preheader ] 112 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 113 %arrayidx7 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv.next, i64 %indvars.iv.next29 114 %2 = load i32, i32* %arrayidx7 115 %add8 = add nsw i32 %2, %k 116 store i32 %add8, i32* %arrayidx7 117 %lftr.wideiv = trunc i64 %indvars.iv to i32 118 %exitcond = icmp eq i32 %lftr.wideiv, %0 119 br i1 %exitcond, label %for.cond.loopexit, label %for.body4 120 121 for.end17: 122 ret void 123} 124 125; CHECK: --- !Missed 126; CHECK-NEXT: Pass: loop-interchange 127; CHECK-NEXT: Name: Dependence 128; CHECK-NEXT: Function: test02 129; CHECK-NEXT: Args: 130; CHECK-NEXT: - String: Cannot interchange loops due to dependences. 131; CHECK-NEXT: ... 132 133; DELIN: --- !Missed 134; DELIN-NEXT: Pass: loop-interchange 135; DELIN-NEXT: Name: UnsupportedInsBetweenInduction 136; DELIN-NEXT: Function: test02 137; DELIN-NEXT: Args: 138; DELIN-NEXT: - String: Found unsupported instruction between induction variable increment and branch. 139; DELIN-NEXT: ... 140 141;;-----------------------------------Test case 03------------------------------- 142;; Test to make sure we can handle output dependencies. 143;; 144;; for (int i = 0; i < 2; ++i) 145;; for(int j = 0; j < 3; ++j) { 146;; A[j][i] = i; 147;; A[j][i+1] = j; 148;; } 149 150@A10 = local_unnamed_addr global [3 x [3 x i32]] zeroinitializer, align 16 151 152define void @test03() { 153entry: 154 br label %for.cond1.preheader 155 156for.cond.loopexit: ; preds = %for.body4 157 %exitcond28 = icmp ne i64 %indvars.iv.next27, 2 158 br i1 %exitcond28, label %for.cond1.preheader, label %for.cond.cleanup 159 160for.cond1.preheader: ; preds = %for.cond.loopexit, %entry 161 %indvars.iv26 = phi i64 [ 0, %entry ], [ %indvars.iv.next27, %for.cond.loopexit ] 162 %indvars.iv.next27 = add nuw nsw i64 %indvars.iv26, 1 163 br label %for.body4 164 165for.cond.cleanup: ; preds = %for.cond.loopexit 166 ret void 167 168for.body4: ; preds = %for.body4, %for.cond1.preheader 169 %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ] 170 %arrayidx6 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* @A10, i64 0, i64 %indvars.iv, i64 %indvars.iv26 171 %tmp = trunc i64 %indvars.iv26 to i32 172 store i32 %tmp, i32* %arrayidx6, align 4 173 %arrayidx10 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* @A10, i64 0, i64 %indvars.iv, i64 %indvars.iv.next27 174 %tmp1 = trunc i64 %indvars.iv to i32 175 store i32 %tmp1, i32* %arrayidx10, align 4 176 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 177 %exitcond = icmp ne i64 %indvars.iv.next, 3 178 br i1 %exitcond, label %for.body4, label %for.cond.loopexit 179} 180 181; CHECK: --- !Missed 182; CHECK-NEXT: Pass: loop-interchange 183; CHECK-NEXT: Name: Dependence 184; CHECK-NEXT: Function: test03 185; CHECK-NEXT: Args: 186; CHECK-NEXT: - String: Cannot interchange loops due to dependences. 187; CHECK-NEXT: ... 188 189; DELIN: --- !Passed 190; DELIN-NEXT: Pass: loop-interchange 191; DELIN-NEXT: Name: Interchanged 192; DELIN-NEXT: Function: test03 193; DELIN-NEXT: Args: 194; DELIN-NEXT: - String: Loop interchanged with enclosing loop. 195; DELIN-NEXT: ... 196 197;;--------------------------------------Test case 04------------------------------------- 198;; Loops not tightly nested are not interchanged 199;; for(int j=0;j<N;j++) { 200;; B[j] = j+k; 201;; for(int i=0;i<N;i++) 202;; A[j][i] = A[j][i]+B[j]; 203;; } 204 205define void @test04(i32 %k, i32 %N){ 206entry: 207 %cmp30 = icmp sgt i32 %N, 0 208 br i1 %cmp30, label %for.body.lr.ph, label %for.end17 209 210for.body.lr.ph: 211 %0 = add i32 %N, -1 212 %1 = zext i32 %k to i64 213 br label %for.body 214 215for.body: 216 %indvars.iv32 = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next33, %for.inc15 ] 217 %2 = add nsw i64 %indvars.iv32, %1 218 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* @C, i64 0, i64 %indvars.iv32 219 %3 = trunc i64 %2 to i32 220 store i32 %3, i32* %arrayidx 221 br label %for.body3 222 223for.body3: 224 %indvars.iv = phi i64 [ 0, %for.body ], [ %indvars.iv.next, %for.body3 ] 225 %arrayidx7 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv32, i64 %indvars.iv 226 %4 = load i32, i32* %arrayidx7 227 %add10 = add nsw i32 %3, %4 228 store i32 %add10, i32* %arrayidx7 229 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 230 %lftr.wideiv = trunc i64 %indvars.iv to i32 231 %exitcond = icmp eq i32 %lftr.wideiv, %0 232 br i1 %exitcond, label %for.inc15, label %for.body3 233 234for.inc15: 235 %indvars.iv.next33 = add nuw nsw i64 %indvars.iv32, 1 236 %lftr.wideiv35 = trunc i64 %indvars.iv32 to i32 237 %exitcond36 = icmp eq i32 %lftr.wideiv35, %0 238 br i1 %exitcond36, label %for.end17, label %for.body 239 240for.end17: 241 ret void 242} 243 244; CHECK: --- !Missed 245; CHECK-NEXT: Pass: loop-interchange 246; CHECK-NEXT: Name: Dependence 247; CHECK-NEXT: Function: test04 248; CHECK-NEXT: Args: 249; CHECK-NEXT: - String: Cannot interchange loops due to dependences. 250; CHECK-NEXT: ... 251 252; DELIN: --- !Missed 253; DELIN-NEXT: Pass: loop-interchange 254; DELIN-NEXT: Name: NotTightlyNested 255; DELIN-NEXT: Function: test04 256; DELIN-NEXT: Args: 257; DELIN-NEXT: - String: Cannot interchange loops because they are not tightly nested. 258; DELIN-NEXT: ... 259