| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt -passes=loop-fusion -loop-fusion-peel-max-count=2 -S < %s 2>&1 | FileCheck %s | |
| ; Test reduced from the file diags_on_lat_aux_grid.F90 present in pop2, | |
| ; a program from spec 2017. Two loops have different guards, but otherwise | |
| ; satisfy all conditions for loop fusion, in particular they have the same | |
| ; iteration count. They should not be fused. | |
| define void @diags_on_lat_aux_grid(i1 %cond, i1 %cond1, i1 %0, i1 %1, ptr noalias %b1, ptr noalias %b2, i64 %N) { | |
| ; CHECK-LABEL: define void @diags_on_lat_aux_grid( | |
| ; CHECK-SAME: i1 [[COND:%.*]], i1 [[COND1:%.*]], i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], ptr noalias [[B1:%.*]], ptr noalias [[B2:%.*]], i64 [[N:%.*]]) { | |
| ; CHECK-NEXT: [[_CRITEDGE:.*:]] | |
| ; CHECK-NEXT: br i1 [[COND]], label %[[COMMON_RET:.*]], label %[[THREAD_PRE_SPLIT:.*]] | |
| ; CHECK: [[COMMON_RET]]: | |
| ; CHECK-NEXT: ret void | |
| ; CHECK: [[THREAD_PRE_SPLIT]]: | |
| ; CHECK-NEXT: br i1 [[COND1]], label %[[BB2:.*]], [[DOTLOOPEXIT:label %.*]] | |
| ; CHECK: [[BB2]]: | |
| ; CHECK-NEXT: br i1 [[TMP0]], label %[[DOTLR_PH1333_PREHEADER:.*]], [[DOT_CRIT_EDGE1334:label %.*]] | |
| ; CHECK: [[_LR_PH1333_PREHEADER:.*:]] | |
| ; CHECK-NEXT: br label %[[DOTLR_PH1333:.*]] | |
| ; CHECK: [[_LR_PH1333:.*:]] | |
| ; CHECK-NEXT: [[INDVARS_IV1386:%.*]] = phi i64 [ [[INDVARS_IV_NEXT1387:%.*]], %[[DOTLR_PH1333]] ], [ 0, %[[DOTLR_PH1333_PREHEADER]] ] | |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr [8 x i8], ptr [[B1]], i64 [[INDVARS_IV1386]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP3]], align 8 | |
| ; CHECK-NEXT: [[INDVARS_IV_NEXT1387]] = add i64 [[INDVARS_IV1386]], 1 | |
| ; CHECK-NEXT: [[EXITCOND1389_NOT:%.*]] = icmp eq i64 [[INDVARS_IV1386]], [[N]] | |
| ; CHECK-NEXT: br i1 [[EXITCOND1389_NOT]], [[DOT_CRIT_EDGE1334_LOOPEXIT:label %.*]], label %[[DOTLR_PH1333]] | |
| ; CHECK: [[__CRIT_EDGE1334_LOOPEXIT:.*:]] | |
| ; CHECK-NEXT: br [[DOT_CRIT_EDGE1334]] | |
| ; CHECK: [[__CRIT_EDGE1334:.*:]] | |
| ; CHECK-NEXT: br i1 [[TMP1]], label %[[DOTLR_PH1336_PREHEADER:.*]], [[DOTLOOPEXIT]] | |
| ; CHECK: [[_LR_PH1336_PREHEADER:.*:]] | |
| ; CHECK-NEXT: br label %[[DOTLR_PH1336:.*]] | |
| ; CHECK: [[_LR_PH1336:.*:]] | |
| ; CHECK-NEXT: [[INDVARS_IV1390:%.*]] = phi i64 [ [[INDVARS_IV_NEXT1391:%.*]], %[[DOTLR_PH1336]] ], [ 0, %[[DOTLR_PH1336_PREHEADER]] ] | |
| ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [8 x i8], ptr [[B2]], i64 [[INDVARS_IV1390]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP4]], align 8 | |
| ; CHECK-NEXT: [[INDVARS_IV_NEXT1391]] = add i64 [[INDVARS_IV1390]], 1 | |
| ; CHECK-NEXT: [[EXITCOND1393_NOT:%.*]] = icmp eq i64 [[INDVARS_IV1390]], [[N]] | |
| ; CHECK-NEXT: br i1 [[EXITCOND1393_NOT]], [[DOTLOOPEXIT_LOOPEXIT:label %.*]], label %[[DOTLR_PH1336]] | |
| ; CHECK: [[_LOOPEXIT_LOOPEXIT:.*:]] | |
| ; CHECK-NEXT: br [[DOTLOOPEXIT]] | |
| ; CHECK: [[_LOOPEXIT:.*:]] | |
| ; CHECK-NEXT: store volatile i32 0, ptr [[B1]], align 4 | |
| ; CHECK-NEXT: br label %[[COMMON_RET]] | |
| ; | |
| .critedge: | |
| br i1 %cond, label %common.ret, label %thread-pre-split | |
| common.ret: ; preds = %.loopexit, %.critedge | |
| ret void | |
| thread-pre-split: ; preds = %.critedge | |
| br i1 %cond1, label %2, label %.loopexit | |
| 2: ; preds = %thread-pre-split | |
| br i1 %0, label %.lr.ph1333, label %._crit_edge1334 | |
| .lr.ph1333: ; preds = %.lr.ph1333, %2 | |
| %indvars.iv1386 = phi i64 [ %indvars.iv.next1387, %.lr.ph1333 ], [ 0, %2 ] | |
| %3 = getelementptr [8 x i8], ptr %b1, i64 %indvars.iv1386 | |
| store double 0.000000e+00, ptr %3, align 8 | |
| %indvars.iv.next1387 = add i64 %indvars.iv1386, 1 | |
| %exitcond1389.not = icmp eq i64 %indvars.iv1386, %N | |
| br i1 %exitcond1389.not, label %._crit_edge1334, label %.lr.ph1333 | |
| ._crit_edge1334: ; preds = %.lr.ph1333, %2 | |
| br i1 %1, label %.lr.ph1336, label %.loopexit | |
| .lr.ph1336: ; preds = %.lr.ph1336, %._crit_edge1334 | |
| %indvars.iv1390 = phi i64 [ %indvars.iv.next1391, %.lr.ph1336 ], [ 0, %._crit_edge1334 ] | |
| %5 = getelementptr [8 x i8], ptr %b2, i64 %indvars.iv1390 | |
| store double 0.000000e+00, ptr %5, align 8 | |
| %indvars.iv.next1391 = add i64 %indvars.iv1390, 1 | |
| %exitcond1393.not = icmp eq i64 %indvars.iv1390, %N | |
| br i1 %exitcond1393.not, label %.loopexit, label %.lr.ph1336 | |
| .loopexit: ; preds = %.lr.ph1336, %._crit_edge1334, %thread-pre-split | |
| store volatile i32 0, ptr %b1, align 4 | |
| br label %common.ret | |
| } | |
| ; A modified version of @diags_on_lat_aux_grid in which iteration count of both | |
| ; loops is constant, but loop guards are different and so fusion is not legal. | |
| define void @modified(i1 %0, i1 %1, ptr noalias %b1, ptr noalias %b2, i64 %N) { | |
| ; CHECK-LABEL: define void @modified( | |
| ; CHECK-SAME: i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], ptr noalias [[B1:%.*]], ptr noalias [[B2:%.*]], i64 [[N:%.*]]) { | |
| ; CHECK-NEXT: br i1 [[TMP0]], label %[[DOTLR_PH1333_PREHEADER:.*]], [[DOTLOOPEXIT:label %.*]] | |
| ; CHECK: [[_LR_PH1333_PEEL_BEGIN:.*:]] | |
| ; CHECK-NEXT: br label %[[DOTLR_PH1333_PEEL:.*]] | |
| ; CHECK: [[_LR_PH1333_PEEL:.*:]] | |
| ; CHECK-NEXT: [[INDVARS_IV1386:%.*]] = phi i64 [ [[INDVARS_IV_NEXT1387:%.*]], %[[DOTLR_PH1333_PEEL]] ], [ 0, %[[DOTLR_PH1333_PREHEADER]] ] | |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr [8 x i8], ptr [[B1]], i64 [[INDVARS_IV1386]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP3]], align 8 | |
| ; CHECK-NEXT: [[INDVARS_IV_NEXT1387]] = add i64 [[INDVARS_IV1386]], 1 | |
| ; CHECK-NEXT: [[EXITCOND1389_NOT:%.*]] = icmp eq i64 [[INDVARS_IV1386]], 40 | |
| ; CHECK-NEXT: br i1 [[EXITCOND1389_NOT]], [[DOT_CRIT_EDGE1334_LOOPEXIT:label %.*]], label %[[DOTLR_PH1333_PEEL]] | |
| ; CHECK: [[_LR_PH1333_PEEL_NEXT:.*:]] | |
| ; CHECK-NEXT: br [[DOTLOOPEXIT]] | |
| ; CHECK: [[_LR_PH1333_PEEL_NEXT1:.*:]] | |
| ; CHECK-NEXT: br i1 [[TMP1]], label %[[DOTLR_PH1336_PREHEADER:.*]], [[DOTLOOPEXIT1:label %.*]] | |
| ; CHECK: [[_LR_PH1333_PREHEADER_PEEL_NEWPH:.*:]] | |
| ; CHECK-NEXT: br label %[[DOTLR_PH1333:.*]] | |
| ; CHECK: [[_LR_PH1333:.*:]] | |
| ; CHECK-NEXT: [[INDVARS_IV1390:%.*]] = phi i64 [ [[INDVARS_IV_NEXT1391:%.*]], %[[DOTLR_PH1333]] ], [ 1, %[[DOTLR_PH1336_PREHEADER]] ] | |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [8 x i8], ptr [[B2]], i64 [[INDVARS_IV1390]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP5]], align 8 | |
| ; CHECK-NEXT: [[INDVARS_IV_NEXT1391]] = add i64 [[INDVARS_IV1390]], 1 | |
| ; CHECK-NEXT: [[EXITCOND1393_NOT:%.*]] = icmp eq i64 [[INDVARS_IV1390]], 40 | |
| ; CHECK-NEXT: br i1 [[EXITCOND1393_NOT]], [[DOTLOOPEXIT_LOOPEXIT:label %.*]], label %[[DOTLR_PH1333]] | |
| ; CHECK: [[_LOOPEXIT_LOOPEXIT:.*:]] | |
| ; CHECK-NEXT: br [[DOTLOOPEXIT1]] | |
| ; CHECK: [[_LOOPEXIT:.*:]] | |
| ; CHECK-NEXT: store volatile i32 0, ptr [[B1]], align 4 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| 2: ; preds = %thread-pre-split | |
| br i1 %0, label %.lr.ph1333, label %._crit_edge1334 | |
| .lr.ph1333: ; preds = %.lr.ph1333, %2 | |
| %indvars.iv1386 = phi i64 [ %indvars.iv.next1387, %.lr.ph1333 ], [ 0, %2 ] | |
| %3 = getelementptr [8 x i8], ptr %b1, i64 %indvars.iv1386 | |
| store double 0.000000e+00, ptr %3, align 8 | |
| %indvars.iv.next1387 = add i64 %indvars.iv1386, 1 | |
| %exitcond1389.not = icmp eq i64 %indvars.iv1386, 40 | |
| br i1 %exitcond1389.not, label %._crit_edge1334, label %.lr.ph1333 | |
| ._crit_edge1334: ; preds = %.lr.ph1333, %2 | |
| br i1 %1, label %.lr.ph1336, label %.loopexit | |
| .lr.ph1336: ; preds = %.lr.ph1336, %._crit_edge1334 | |
| %indvars.iv1390 = phi i64 [ %indvars.iv.next1391, %.lr.ph1336 ], [ 1, %._crit_edge1334 ] | |
| %5 = getelementptr [8 x i8], ptr %b2, i64 %indvars.iv1390 | |
| store double 0.000000e+00, ptr %5, align 8 | |
| %indvars.iv.next1391 = add i64 %indvars.iv1390, 1 | |
| %exitcond1393.not = icmp eq i64 %indvars.iv1390, 40 | |
| br i1 %exitcond1393.not, label %.loopexit, label %.lr.ph1336 | |
| .loopexit: ; preds = %.lr.ph1336, %._crit_edge1334 | |
| store volatile i32 0, ptr %b1, align 4 | |
| ret void | |
| } |