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