1; RUN: opt < %s -passes=loop-interchange -cache-line-size=4 -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t -S \ 2; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa 3; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s 4 5@b = external global [512 x [4 x i32]] 6@c = global [2 x [4 x i32]] zeroinitializer, align 1 7 8; Check that the outermost and the middle loops are not interchanged since 9; the innermost loop has a reduction operation which is however not in a form 10; that loop interchange can handle. Interchanging the outermost and the 11; middle loops would intervene with the reduction and cause miscompile. 12 13; REMARKS: --- !Missed 14; REMARKS-NEXT: Pass: loop-interchange 15; REMARKS-NEXT: Name: UnsupportedPHIInner 16; REMARKS-NEXT: Function: test7 17; REMARKS: --- !Missed 18; REMARKS-NEXT: Pass: loop-interchange 19; REMARKS-NEXT: Name: UnsupportedPHIInner 20; REMARKS-NEXT: Function: test7 21 22define i32 @test7() { 23entry: 24 br label %for.cond1.preheader.i 25 26for.cond1.preheader.i: ; preds = %for.inc19.i, %entry 27 %i.011.i = phi i16 [ 0, %entry ], [ %inc20.i, %for.inc19.i ] 28 br label %for.cond4.preheader.i 29 30for.cond4.preheader.i: ; preds = %middle.block, %for.cond1.preheader.i 31 %j.010.i = phi i16 [ 0, %for.cond1.preheader.i ], [ %inc17.i, %middle.block ] 32 %arrayidx14.i = getelementptr inbounds [2 x [4 x i32]], ptr @c, i16 0, i16 %i.011.i, i16 %j.010.i 33 %arrayidx14.promoted.i = load i32, ptr %arrayidx14.i, align 1 34 %0 = insertelement <4 x i32> <i32 poison, i32 0, i32 0, i32 0>, i32 %arrayidx14.promoted.i, i64 0 35 br label %vector.body 36 37vector.body: ; preds = %vector.body, %for.cond4.preheader.i 38 %index = phi i16 [ 0, %for.cond4.preheader.i ], [ %index.next, %vector.body ] 39 %vec.phi = phi <4 x i32> [ %0, %for.cond4.preheader.i ], [ %16, %vector.body ] 40 %1 = or i16 %index, 1 41 %2 = or i16 %index, 2 42 %3 = or i16 %index, 3 43 %4 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %index, i16 %j.010.i 44 %5 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %1, i16 %j.010.i 45 %6 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %2, i16 %j.010.i 46 %7 = getelementptr inbounds [512 x [4 x i32]], ptr @b, i16 0, i16 %3, i16 %j.010.i 47 %8 = load i32, ptr %4, align 1 48 %9 = load i32, ptr %5, align 1 49 %10 = load i32, ptr %6, align 1 50 %11 = load i32, ptr %7, align 1 51 %12 = insertelement <4 x i32> poison, i32 %8, i64 0 52 %13 = insertelement <4 x i32> %12, i32 %9, i64 1 53 %14 = insertelement <4 x i32> %13, i32 %10, i64 2 54 %15 = insertelement <4 x i32> %14, i32 %11, i64 3 55 %16 = add <4 x i32> %15, %vec.phi 56 %index.next = add nuw i16 %index, 4 57 %17 = icmp eq i16 %index.next, 512 58 br i1 %17, label %middle.block, label %vector.body 59 60middle.block: ; preds = %vector.body 61 %18 = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %16) 62 store i32 %18, ptr %arrayidx14.i, align 1 63 %inc17.i = add nuw nsw i16 %j.010.i, 1 64 %exitcond12.not.i = icmp eq i16 %inc17.i, 4 65 br i1 %exitcond12.not.i, label %for.inc19.i, label %for.cond4.preheader.i 66 67for.inc19.i: ; preds = %middle.block 68 %inc20.i = add nuw nsw i16 %i.011.i, 1 69 %exitcond13.not.i = icmp eq i16 %inc20.i, 2 70 br i1 %exitcond13.not.i, label %test.exit, label %for.cond1.preheader.i 71 72test.exit: ; preds = %for.inc19.i 73 %19 = load i32, ptr @c, align 1 74 ret i32 %19 75} 76 77declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>) 78