1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker;; We test profitability model in these test cases. 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu" 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker@A = common global [100 x [100 x i32]] zeroinitializer 8*9880d681SAndroid Build Coastguard Worker@B = common global [100 x [100 x i32]] zeroinitializer 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker;;---------------------------------------Test case 01--------------------------------- 11*9880d681SAndroid Build Coastguard Worker;; Loops interchange will result in code vectorization and hence profitable. Check for interchange. 12*9880d681SAndroid Build Coastguard Worker;; for(int i=1;i<N;i++) 13*9880d681SAndroid Build Coastguard Worker;; for(int j=1;j<N;j++) 14*9880d681SAndroid Build Coastguard Worker;; A[j][i] = A[j - 1][i] + B[j][i]; 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Workerdefine void @interchange_01(i32 %N) { 17*9880d681SAndroid Build Coastguard Workerentry: 18*9880d681SAndroid Build Coastguard Worker %cmp27 = icmp sgt i32 %N, 1 19*9880d681SAndroid Build Coastguard Worker br i1 %cmp27, label %for.cond1.preheader.lr.ph, label %for.end16 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Workerfor.cond1.preheader.lr.ph: 22*9880d681SAndroid Build Coastguard Worker %0 = add i32 %N, -1 23*9880d681SAndroid Build Coastguard Worker br label %for.body3.preheader 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Workerfor.body3.preheader: 26*9880d681SAndroid Build Coastguard Worker %indvars.iv30 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next31, %for.inc14 ] 27*9880d681SAndroid Build Coastguard Worker br label %for.body3 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Workerfor.body3: 30*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 1, %for.body3.preheader ] 31*9880d681SAndroid Build Coastguard Worker %1 = add nsw i64 %indvars.iv, -1 32*9880d681SAndroid Build Coastguard Worker %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %indvars.iv30 33*9880d681SAndroid Build Coastguard Worker %2 = load i32, i32* %arrayidx5 34*9880d681SAndroid Build Coastguard Worker %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv, i64 %indvars.iv30 35*9880d681SAndroid Build Coastguard Worker %3 = load i32, i32* %arrayidx9 36*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %3, %2 37*9880d681SAndroid Build Coastguard Worker %arrayidx13 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv30 38*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %arrayidx13 39*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 40*9880d681SAndroid Build Coastguard Worker %lftr.wideiv = trunc i64 %indvars.iv to i32 41*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %lftr.wideiv, %0 42*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.inc14, label %for.body3 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Workerfor.inc14: 45*9880d681SAndroid Build Coastguard Worker %indvars.iv.next31 = add nuw nsw i64 %indvars.iv30, 1 46*9880d681SAndroid Build Coastguard Worker %lftr.wideiv32 = trunc i64 %indvars.iv30 to i32 47*9880d681SAndroid Build Coastguard Worker %exitcond33 = icmp eq i32 %lftr.wideiv32, %0 48*9880d681SAndroid Build Coastguard Worker br i1 %exitcond33, label %for.end16, label %for.body3.preheader 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerfor.end16: 51*9880d681SAndroid Build Coastguard Worker ret void 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker;; Here we are checking partial .ll to check if loop are interchanged. 54*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @interchange_01 55*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.preheader: ; preds = %for.inc14, %for.cond1.preheader.lr.ph 56*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv30 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next31, %for.inc14 ] 57*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.body3.split2 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.preheader1: ; preds = %entry 60*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.body3 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3: ; preds = %for.body3.preheader1, %for.body3.split 63*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3.split ], [ 1, %for.body3.preheader1 ] 64*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.cond1.preheader.lr.ph 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.split2: ; preds = %for.body3.preheader 67*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = add nsw i64 %indvars.iv, -1 68*9880d681SAndroid Build Coastguard Worker; CHECK: %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %indvars.iv30 69*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = load i32, i32* %arrayidx5 70*9880d681SAndroid Build Coastguard Worker; CHECK: %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv, i64 %indvars.iv30 71*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = load i32, i32* %arrayidx9 72*9880d681SAndroid Build Coastguard Worker; CHECK: %add = add nsw i32 %3, %2 73*9880d681SAndroid Build Coastguard Worker; CHECK: %arrayidx13 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv30 74*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 %add, i32* %arrayidx13 75*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.inc14 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker;; ---------------------------------------Test case 02--------------------------------- 79*9880d681SAndroid Build Coastguard Worker;; Check loop interchange profitability model. 80*9880d681SAndroid Build Coastguard Worker;; This tests profitability model when operands of getelementpointer and not exactly the induction variable but some 81*9880d681SAndroid Build Coastguard Worker;; arithmetic operation on them. 82*9880d681SAndroid Build Coastguard Worker;; for(int i=1;i<N;i++) 83*9880d681SAndroid Build Coastguard Worker;; for(int j=1;j<N;j++) 84*9880d681SAndroid Build Coastguard Worker;; A[j-1][i-1] = A[j - 1][i-1] + B[j-1][i-1]; 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerdefine void @interchange_02(i32 %N) { 87*9880d681SAndroid Build Coastguard Workerentry: 88*9880d681SAndroid Build Coastguard Worker %cmp32 = icmp sgt i32 %N, 1 89*9880d681SAndroid Build Coastguard Worker br i1 %cmp32, label %for.cond1.preheader.lr.ph, label %for.end21 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Workerfor.cond1.preheader.lr.ph: 92*9880d681SAndroid Build Coastguard Worker %0 = add i32 %N, -1 93*9880d681SAndroid Build Coastguard Worker br label %for.body3.lr.ph 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Workerfor.body3.lr.ph: 96*9880d681SAndroid Build Coastguard Worker %indvars.iv35 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next36, %for.inc19 ] 97*9880d681SAndroid Build Coastguard Worker %1 = add nsw i64 %indvars.iv35, -1 98*9880d681SAndroid Build Coastguard Worker br label %for.body3 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Workerfor.body3: 101*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 1, %for.body3.lr.ph ], [ %indvars.iv.next, %for.body3 ] 102*9880d681SAndroid Build Coastguard Worker %2 = add nsw i64 %indvars.iv, -1 103*9880d681SAndroid Build Coastguard Worker %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %2, i64 %1 104*9880d681SAndroid Build Coastguard Worker %3 = load i32, i32* %arrayidx6 105*9880d681SAndroid Build Coastguard Worker %arrayidx12 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %2, i64 %1 106*9880d681SAndroid Build Coastguard Worker %4 = load i32, i32* %arrayidx12 107*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %4, %3 108*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %arrayidx6 109*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 110*9880d681SAndroid Build Coastguard Worker %lftr.wideiv = trunc i64 %indvars.iv to i32 111*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %lftr.wideiv, %0 112*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.inc19, label %for.body3 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Workerfor.inc19: 115*9880d681SAndroid Build Coastguard Worker %indvars.iv.next36 = add nuw nsw i64 %indvars.iv35, 1 116*9880d681SAndroid Build Coastguard Worker %lftr.wideiv38 = trunc i64 %indvars.iv35 to i32 117*9880d681SAndroid Build Coastguard Worker %exitcond39 = icmp eq i32 %lftr.wideiv38, %0 118*9880d681SAndroid Build Coastguard Worker br i1 %exitcond39, label %for.end21, label %for.body3.lr.ph 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Workerfor.end21: 121*9880d681SAndroid Build Coastguard Worker ret void 122*9880d681SAndroid Build Coastguard Worker} 123*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @interchange_02 124*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.lr.ph: ; preds = %for.inc19, %for.cond1.preheader.lr.ph 125*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv35 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next36, %for.inc19 ] 126*9880d681SAndroid Build Coastguard Worker; CHECK: %0 = add nsw i64 %indvars.iv35, -1 127*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.body3.split1 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.preheader: ; preds = %entry 130*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = add i32 %N, -1 131*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.body3 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3: ; preds = %for.body3.preheader, %for.body3.split 134*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3.split ], [ 1, %for.body3.preheader ] 135*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.cond1.preheader.lr.ph 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.split1: ; preds = %for.body3.lr.ph 138*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = add nsw i64 %indvars.iv, -1 139*9880d681SAndroid Build Coastguard Worker; CHECK: %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %2, i64 %0 140*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = load i32, i32* %arrayidx6 141*9880d681SAndroid Build Coastguard Worker; CHECK: %arrayidx12 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %2, i64 %0 142*9880d681SAndroid Build Coastguard Worker; CHECK: %4 = load i32, i32* %arrayidx12 143*9880d681SAndroid Build Coastguard Worker; CHECK: %add = add nsw i32 %4, %3 144*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 %add, i32* %arrayidx6 145*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.inc19 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker;;---------------------------------------Test case 03--------------------------------- 149*9880d681SAndroid Build Coastguard Worker;; Loops interchange is not profitable. 150*9880d681SAndroid Build Coastguard Worker;; for(int i=1;i<N;i++) 151*9880d681SAndroid Build Coastguard Worker;; for(int j=1;j<N;j++) 152*9880d681SAndroid Build Coastguard Worker;; A[i-1][j-1] = A[i - 1][j-1] + B[i][j]; 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Workerdefine void @interchange_03(i32 %N){ 155*9880d681SAndroid Build Coastguard Workerentry: 156*9880d681SAndroid Build Coastguard Worker %cmp31 = icmp sgt i32 %N, 1 157*9880d681SAndroid Build Coastguard Worker br i1 %cmp31, label %for.cond1.preheader.lr.ph, label %for.end19 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Workerfor.cond1.preheader.lr.ph: 160*9880d681SAndroid Build Coastguard Worker %0 = add i32 %N, -1 161*9880d681SAndroid Build Coastguard Worker br label %for.body3.lr.ph 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Workerfor.body3.lr.ph: 164*9880d681SAndroid Build Coastguard Worker %indvars.iv34 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next35, %for.inc17 ] 165*9880d681SAndroid Build Coastguard Worker %1 = add nsw i64 %indvars.iv34, -1 166*9880d681SAndroid Build Coastguard Worker br label %for.body3 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Workerfor.body3: 169*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 1, %for.body3.lr.ph ], [ %indvars.iv.next, %for.body3 ] 170*9880d681SAndroid Build Coastguard Worker %2 = add nsw i64 %indvars.iv, -1 171*9880d681SAndroid Build Coastguard Worker %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %2 172*9880d681SAndroid Build Coastguard Worker %3 = load i32, i32* %arrayidx6 173*9880d681SAndroid Build Coastguard Worker %arrayidx10 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv34, i64 %indvars.iv 174*9880d681SAndroid Build Coastguard Worker %4 = load i32, i32* %arrayidx10 175*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %4, %3 176*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %arrayidx6 177*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 178*9880d681SAndroid Build Coastguard Worker %lftr.wideiv = trunc i64 %indvars.iv to i32 179*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %lftr.wideiv, %0 180*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.inc17, label %for.body3 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerfor.inc17: 183*9880d681SAndroid Build Coastguard Worker %indvars.iv.next35 = add nuw nsw i64 %indvars.iv34, 1 184*9880d681SAndroid Build Coastguard Worker %lftr.wideiv37 = trunc i64 %indvars.iv34 to i32 185*9880d681SAndroid Build Coastguard Worker %exitcond38 = icmp eq i32 %lftr.wideiv37, %0 186*9880d681SAndroid Build Coastguard Worker br i1 %exitcond38, label %for.end19, label %for.body3.lr.ph 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Workerfor.end19: 189*9880d681SAndroid Build Coastguard Worker ret void 190*9880d681SAndroid Build Coastguard Worker} 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @interchange_03 193*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.lr.ph: 194*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv34 = phi i64 [ 1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next35, %for.inc17 ] 195*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = add nsw i64 %indvars.iv34, -1 196*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.body3.preheader 197*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3.preheader: 198*9880d681SAndroid Build Coastguard Worker; CHECK: br label %for.body3 199*9880d681SAndroid Build Coastguard Worker; CHECK: for.body3: 200*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 1, %for.body3.preheader ] 201*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = add nsw i64 %indvars.iv, -1 202*9880d681SAndroid Build Coastguard Worker; CHECK: %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %1, i64 %2 203*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = load i32, i32* %arrayidx6 204*9880d681SAndroid Build Coastguard Worker; CHECK: %arrayidx10 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @B, i64 0, i64 %indvars.iv34, i64 %indvars.iv 205*9880d681SAndroid Build Coastguard Worker; CHECK: %4 = load i32, i32* %arrayidx10 206