1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -loop-interchange -verify-loop-lcssa -S %s | FileCheck %s 3 4; Tests for PR43797. 5 6@wdtdr = external dso_local global [5 x [5 x double]], align 16 7 8define void @test1() { 9; CHECK-LABEL: @test1( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: br label [[INNER_HEADER_PREHEADER:%.*]] 12; CHECK: outer.header.preheader: 13; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] 14; CHECK: outer.header: 15; CHECK-NEXT: [[OUTER_IDX:%.*]] = phi i64 [ [[OUTER_IDX_INC:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[OUTER_HEADER_PREHEADER:%.*]] ] 16; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 [[OUTER_IDX]] 17; CHECK-NEXT: br label [[INNER_HEADER_SPLIT:%.*]] 18; CHECK: inner.header.preheader: 19; CHECK-NEXT: br label [[INNER_HEADER:%.*]] 20; CHECK: inner.header: 21; CHECK-NEXT: [[INNER_IDX:%.*]] = phi i64 [ [[TMP3:%.*]], [[INNER_LATCH_SPLIT:%.*]] ], [ 0, [[INNER_HEADER_PREHEADER]] ] 22; CHECK-NEXT: br label [[OUTER_HEADER_PREHEADER]] 23; CHECK: inner.header.split: 24; CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[ARRAYIDX8]], align 8 25; CHECK-NEXT: store double undef, double* [[ARRAYIDX8]], align 8 26; CHECK-NEXT: br label [[INNER_LATCH:%.*]] 27; CHECK: inner.latch: 28; CHECK-NEXT: [[INNER_IDX_INC:%.*]] = add nsw i64 [[INNER_IDX]], 1 29; CHECK-NEXT: br label [[INNER_EXIT:%.*]] 30; CHECK: inner.latch.split: 31; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ [[OUTER_V:%.*]], [[OUTER_LATCH]] ] 32; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ [[OUTER_IDX_INC]], [[OUTER_LATCH]] ] 33; CHECK-NEXT: [[TMP3]] = add nsw i64 [[INNER_IDX]], 1 34; CHECK-NEXT: br i1 false, label [[INNER_HEADER]], label [[OUTER_EXIT:%.*]] 35; CHECK: inner.exit: 36; CHECK-NEXT: [[OUTER_V]] = add nsw i64 [[OUTER_IDX]], 1 37; CHECK-NEXT: br label [[OUTER_LATCH]] 38; CHECK: outer.latch: 39; CHECK-NEXT: [[OUTER_IDX_INC]] = add nsw i64 [[OUTER_IDX]], 1 40; CHECK-NEXT: br i1 false, label [[OUTER_HEADER]], label [[INNER_LATCH_SPLIT]] 41; CHECK: outer.exit: 42; CHECK-NEXT: [[EXIT1_LCSSA:%.*]] = phi i64 [ [[TMP1]], [[INNER_LATCH_SPLIT]] ] 43; CHECK-NEXT: [[EXIT2_LCSSA:%.*]] = phi i64 [ [[TMP2]], [[INNER_LATCH_SPLIT]] ] 44; CHECK-NEXT: ret void 45; 46entry: 47 br label %outer.header 48 49outer.header: ; preds = %for.inc27, %entry 50 %outer.idx = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ] 51 %arrayidx8 = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 %outer.idx 52 br label %inner.header 53 54inner.header: ; preds = %for.inc, %for.body 55 %inner.idx = phi i64 [ 0, %outer.header ], [ %inner.idx.inc, %inner.latch] 56 %0 = load double, double* %arrayidx8, align 8 57 store double undef, double* %arrayidx8, align 8 58 br label %inner.latch 59 60inner.latch: ; preds = %for.body6 61 %inner.idx.inc = add nsw i64 %inner.idx, 1 62 br i1 undef, label %inner.header, label %inner.exit 63 64inner.exit: ; preds = %for.inc 65 %outer.v = add nsw i64 %outer.idx, 1 66 br label %outer.latch 67 68outer.latch: ; preds = %for.end 69 %outer.idx.inc = add nsw i64 %outer.idx, 1 70 br i1 undef, label %outer.header, label %outer.exit 71 72outer.exit: ; preds = %for.inc27 73 %exit1.lcssa = phi i64 [ %outer.v, %outer.latch ] 74 %exit2.lcssa = phi i64 [ %outer.idx.inc, %outer.latch ] 75 ret void 76} 77 78define void @test2(i1 %cond) { 79; CHECK-LABEL: @test2( 80; CHECK-NEXT: entry: 81; CHECK-NEXT: br i1 [[COND:%.*]], label [[INNER_HEADER_PREHEADER:%.*]], label [[OUTER_EXIT:%.*]] 82; CHECK: outer.header.preheader: 83; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] 84; CHECK: outer.header: 85; CHECK-NEXT: [[OUTER_IDX:%.*]] = phi i64 [ [[OUTER_IDX_INC:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[OUTER_HEADER_PREHEADER:%.*]] ] 86; CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 [[OUTER_IDX]] 87; CHECK-NEXT: br label [[INNER_HEADER_SPLIT:%.*]] 88; CHECK: inner.header.preheader: 89; CHECK-NEXT: br label [[INNER_HEADER:%.*]] 90; CHECK: inner.header: 91; CHECK-NEXT: [[INNER_IDX:%.*]] = phi i64 [ [[TMP3:%.*]], [[INNER_LATCH_SPLIT:%.*]] ], [ 0, [[INNER_HEADER_PREHEADER]] ] 92; CHECK-NEXT: br label [[OUTER_HEADER_PREHEADER]] 93; CHECK: inner.header.split: 94; CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[ARRAYIDX8]], align 8 95; CHECK-NEXT: store double undef, double* [[ARRAYIDX8]], align 8 96; CHECK-NEXT: br label [[INNER_LATCH:%.*]] 97; CHECK: inner.latch: 98; CHECK-NEXT: [[INNER_IDX_INC:%.*]] = add nsw i64 [[INNER_IDX]], 1 99; CHECK-NEXT: br label [[INNER_EXIT:%.*]] 100; CHECK: inner.latch.split: 101; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ [[OUTER_IDX_INC]], [[OUTER_LATCH]] ] 102; CHECK-NEXT: [[TMP2:%.*]] = phi i64 [ [[OUTER_V:%.*]], [[OUTER_LATCH]] ] 103; CHECK-NEXT: [[TMP3]] = add nsw i64 [[INNER_IDX]], 1 104; CHECK-NEXT: br i1 false, label [[INNER_HEADER]], label [[OUTER_EXIT_LOOPEXIT:%.*]] 105; CHECK: inner.exit: 106; CHECK-NEXT: [[OUTER_V]] = add nsw i64 [[OUTER_IDX]], 1 107; CHECK-NEXT: br label [[OUTER_LATCH]] 108; CHECK: outer.latch: 109; CHECK-NEXT: [[OUTER_IDX_INC]] = add nsw i64 [[OUTER_IDX]], 1 110; CHECK-NEXT: br i1 false, label [[OUTER_HEADER]], label [[INNER_LATCH_SPLIT]] 111; CHECK: outer.exit.loopexit: 112; CHECK-NEXT: [[OUTER_IDX_INC_LCSSA:%.*]] = phi i64 [ [[TMP1]], [[INNER_LATCH_SPLIT]] ] 113; CHECK-NEXT: [[OUTER_V_LCSSA:%.*]] = phi i64 [ [[TMP2]], [[INNER_LATCH_SPLIT]] ] 114; CHECK-NEXT: br label [[OUTER_EXIT]] 115; CHECK: outer.exit: 116; CHECK-NEXT: [[EXIT1_LCSSA:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_V_LCSSA]], [[OUTER_EXIT_LOOPEXIT]] ] 117; CHECK-NEXT: [[EXIT2_LCSSA:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[OUTER_IDX_INC_LCSSA]], [[OUTER_EXIT_LOOPEXIT]] ] 118; CHECK-NEXT: ret void 119; 120entry: 121 br i1 %cond, label %outer.header, label %outer.exit 122 123outer.header: ; preds = %for.inc27, %entry 124 %outer.idx = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ] 125 %arrayidx8 = getelementptr inbounds [5 x [5 x double]], [5 x [5 x double]]* @wdtdr, i64 0, i64 0, i64 %outer.idx 126 br label %inner.header 127 128inner.header: ; preds = %for.inc, %for.body 129 %inner.idx = phi i64 [ 0, %outer.header ], [ %inner.idx.inc, %inner.latch] 130 %0 = load double, double* %arrayidx8, align 8 131 store double undef, double* %arrayidx8, align 8 132 br label %inner.latch 133 134inner.latch: ; preds = %for.body6 135 %inner.idx.inc = add nsw i64 %inner.idx , 1 136 br i1 undef, label %inner.header, label %inner.exit 137 138inner.exit: ; preds = %for.inc 139 %outer.v = add nsw i64 %outer.idx, 1 140 br label %outer.latch 141 142outer.latch: ; preds = %for.end 143 %outer.idx.inc = add nsw i64 %outer.idx, 1 144 br i1 undef, label %outer.header, label %outer.exit 145 146outer.exit: ; preds = %for.inc27 147 %exit1.lcssa = phi i64 [ 0, %entry ], [ %outer.v, %outer.latch ] 148 %exit2.lcssa = phi i64 [ 0, %entry ], [ %outer.idx.inc, %outer.latch ] 149 ret void 150} 151