1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes=loop-unroll -unroll-allow-partial | FileCheck %s 3 4; The phi which acts as input to func should not be undef. It should 5; have its loop-carried value (the load in for.cond) replaced accordingly 6; after unrolling the loop. 7 8define i16 @full_unroll(ptr %A) { 9; CHECK-LABEL: @full_unroll( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: br label [[FOR_COND:%.*]] 12; CHECK: for.cond: 13; CHECK-NEXT: br label [[FOR_COND_CLEANUP3:%.*]] 14; CHECK: for.cond.cleanup: 15; CHECK-NEXT: [[DOTLCSSA10_LCSSA:%.*]] = phi i16 [ [[TMP2_2:%.*]], [[FOR_COND_CLEANUP3_2:%.*]] ] 16; CHECK-NEXT: [[TMP3:%.*]] = call i16 @func(i16 [[DOTLCSSA10_LCSSA]]) 17; CHECK-NEXT: ret i16 0 18; CHECK: for.cond.cleanup3: 19; CHECK-NEXT: br label [[FOR_COND_CLEANUP3_1:%.*]] 20; CHECK: for.cond.cleanup3.1: 21; CHECK-NEXT: [[PTR_2:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 2 22; CHECK-NEXT: [[TMP2_2]] = load i16, ptr [[PTR_2]], align 2 23; CHECK-NEXT: br label [[FOR_COND_CLEANUP3_2]] 24; CHECK: for.cond.cleanup3.2: 25; CHECK-NEXT: br i1 false, label [[FOR_COND_CLEANUP3_3:%.*]], label [[FOR_COND_CLEANUP:%.*]] 26; CHECK: for.cond.cleanup3.3: 27; CHECK-NEXT: unreachable 28; 29entry: 30 br label %for.cond 31 32for.cond: ; preds = %for.cond.cleanup3, %entry 33 %.lcssa10 = phi i16 [ 123, %entry ], [ %.lcssa, %for.cond.cleanup3 ] 34 %i.0 = phi i64 [ 0, %entry ], [ %inc9, %for.cond.cleanup3 ] 35 %ptr = getelementptr inbounds i16, ptr %A, i64 %i.0 36 %tmp2 = load i16, ptr %ptr 37 %cmp = icmp ult i64 %i.0, 3 38 br i1 %cmp, label %for.cond.cleanup3, label %for.cond.cleanup 39 40for.cond.cleanup: ; preds = %for.cond 41 %.lcssa10.lcssa = phi i16 [ %.lcssa10, %for.cond ] 42 %tmp3 = call i16 (i16) @func(i16 %.lcssa10.lcssa) 43 ret i16 0 44 45for.cond.cleanup3: ; preds = %for.cond 46 %.lcssa = phi i16 [ %tmp2, %for.cond ] 47 %inc9 = add i64 %i.0, 1 48 br label %for.cond 49} 50 51define i16 @partial_unroll(ptr %A) { 52; CHECK-LABEL: @partial_unroll( 53; CHECK-NEXT: entry: 54; CHECK-NEXT: br label [[FOR_COND:%.*]] 55; CHECK: for.cond: 56; CHECK-NEXT: [[I_0:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC9_2:%.*]], [[FOR_COND_CLEANUP3_2:%.*]] ] 57; CHECK-NEXT: br label [[FOR_COND_CLEANUP3:%.*]] 58; CHECK: for.cond.cleanup: 59; CHECK-NEXT: [[DOTLCSSA10_LCSSA:%.*]] = phi i16 [ [[TMP2_1:%.*]], [[FOR_COND_CLEANUP3_1:%.*]] ] 60; CHECK-NEXT: [[TMP3:%.*]] = call i16 @func(i16 [[DOTLCSSA10_LCSSA]]) 61; CHECK-NEXT: ret i16 0 62; CHECK: for.cond.cleanup3: 63; CHECK-NEXT: [[INC9:%.*]] = add nuw nsw i64 [[I_0]], 1 64; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[INC9]] 65; CHECK-NEXT: [[TMP2_1]] = load i16, ptr [[PTR_1]], align 2 66; CHECK-NEXT: br label [[FOR_COND_CLEANUP3_1]] 67; CHECK: for.cond.cleanup3.1: 68; CHECK-NEXT: [[INC9_1:%.*]] = add nuw nsw i64 [[I_0]], 2 69; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i64 [[INC9_1]], 200 70; CHECK-NEXT: br i1 [[CMP_2]], label [[FOR_COND_CLEANUP3_2]], label [[FOR_COND_CLEANUP:%.*]] 71; CHECK: for.cond.cleanup3.2: 72; CHECK-NEXT: [[INC9_2]] = add nuw nsw i64 [[I_0]], 3 73; CHECK-NEXT: br label [[FOR_COND]] 74; 75entry: 76 br label %for.cond 77 78for.cond: ; preds = %for.cond.cleanup3, %entry 79 %.lcssa10 = phi i16 [ 123, %entry ], [ %.lcssa, %for.cond.cleanup3 ] 80 %i.0 = phi i64 [ 0, %entry ], [ %inc9, %for.cond.cleanup3 ] 81 %ptr = getelementptr inbounds i16, ptr %A, i64 %i.0 82 %tmp2 = load i16, ptr %ptr 83 %cmp = icmp ult i64 %i.0, 200 84 br i1 %cmp, label %for.cond.cleanup3, label %for.cond.cleanup 85 86for.cond.cleanup: ; preds = %for.cond 87 %.lcssa10.lcssa = phi i16 [ %.lcssa10, %for.cond ] 88 %tmp3 = call i16 (i16) @func(i16 %.lcssa10.lcssa) 89 ret i16 0 90 91for.cond.cleanup3: ; preds = %for.cond 92 %.lcssa = phi i16 [ %tmp2, %for.cond ] 93 %inc9 = add i64 %i.0, 1 94 br label %for.cond 95} 96 97declare i16 @func(i16) 98 99