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