151 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -S -passes=loop-unroll -enable-peeling-for-iv | FileCheck %s3; RUN: opt < %s -S -passes=loop-unroll-full -enable-peeling-for-iv | FileCheck %s4 5; Check that unnecessary peeling doesn't occur if for a comparison instruction6; between two instructions. The original code is as below. Both i and j are7; inductions, but the comparison i < j is not an induction.8;9; val = 42;10; for (i=0,j=100; i<10000; i+=2,j+=1) {11; a[i] = val;12; val = i < j;13; }14;15define void @dont_peel_cmp_ind_ind(ptr %a) {16; CHECK-LABEL: define void @dont_peel_cmp_ind_ind(17; CHECK-SAME: ptr [[A:%.*]]) {18; CHECK-NEXT: [[ENTRY:.*]]:19; CHECK-NEXT: br label %[[FOR_BODY:.*]]20; CHECK: [[FOR_BODY]]:21; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[FOR_BODY]] ]22; CHECK-NEXT: [[J:%.*]] = phi i32 [ 100, %[[ENTRY]] ], [ [[J_NEXT:%.*]], %[[FOR_BODY]] ]23; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ 42, %[[ENTRY]] ], [ [[VAL_NEXT:%.*]], %[[FOR_BODY]] ]24; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i32 [[I]]25; CHECK-NEXT: store i32 10, ptr [[ARRAYIDX]], align 426; CHECK-NEXT: [[VAL_NEXT_CMP:%.*]] = icmp slt i32 [[I]], [[J]]27; CHECK-NEXT: [[VAL_NEXT]] = zext i1 [[VAL_NEXT_CMP]] to i3228; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 229; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 130; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I_NEXT]], 1000031; CHECK-NEXT: [[EXITCOND:%.*]] = icmp slt i32 [[I_NEXT]], 1000032; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_BODY]], label %[[EXIT:.*]]33; CHECK: [[EXIT]]:34; CHECK-NEXT: ret void35;36entry:37 br label %for.body38 39for.body:40 %i = phi i32 [ 0, %entry ], [ %i.next, %for.body ]41 %j = phi i32 [ 100, %entry ] , [ %j.next, %for.body ]42 %val = phi i32 [ 42, %entry ], [ %val.next, %for.body ]43 %arrayidx = getelementptr inbounds nuw i32, ptr %a, i32 %i44 store i32 10, ptr %arrayidx, align 445 %val.next.cmp = icmp slt i32 %i, %j46 %val.next = zext i1 %val.next.cmp to i3247 %i.next = add i32 %i, 248 %j.next = add i32 %j, 149 %cmp = icmp ne i32 %i.next, 1000050 %exitcond = icmp slt i32 %i.next, 1000051 br i1 %exitcond, label %for.body, label %exit52 53exit:54 ret void55}56 57 58; Check that unnecessary peeling doesn't occur if for a bitwise instructions59; between IVs. The original code is as below. The variable i is an induction,60; but vals (val0 through val4) are not.61;62; val0 = 42;63; val1 = 42;64; val2 = 42;65; val3 = 42;66; val4 = 42;67; for (i=0,j=100; i<10000; i+=2,j+=1) {68; a[i] = val0;69; b[i] = val1;70; c[i] = val2;71; d[i] = val3;72; e[i] = val4;73; val0 = i & j;74; val1 = i | j;75; val2 = i ^ j;76; val3 = i >> j;77; val4 = i << j;78; }79;80define void @dont_peel_bitwise_op_iv_iv(ptr %a, ptr %b, ptr %c, ptr %d, ptr %e) {81; CHECK-LABEL: define void @dont_peel_bitwise_op_iv_iv(82; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], ptr [[E:%.*]]) {83; CHECK-NEXT: [[ENTRY:.*]]:84; CHECK-NEXT: br label %[[FOR_BODY:.*]]85; CHECK: [[FOR_BODY]]:86; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[FOR_BODY]] ]87; CHECK-NEXT: [[J:%.*]] = phi i32 [ 100, %[[ENTRY]] ], [ [[J_NEXT:%.*]], %[[FOR_BODY]] ]88; CHECK-NEXT: [[VAL0:%.*]] = phi i32 [ 42, %[[ENTRY]] ], [ [[VAL0_NEXT:%.*]], %[[FOR_BODY]] ]89; CHECK-NEXT: [[VAL1:%.*]] = phi i32 [ 42, %[[ENTRY]] ], [ [[VAL1_NEXT:%.*]], %[[FOR_BODY]] ]90; CHECK-NEXT: [[VAL2:%.*]] = phi i32 [ 42, %[[ENTRY]] ], [ [[VAL2_NEXT:%.*]], %[[FOR_BODY]] ]91; CHECK-NEXT: [[VAL3:%.*]] = phi i32 [ 42, %[[ENTRY]] ], [ [[VAL3_NEXT:%.*]], %[[FOR_BODY]] ]92; CHECK-NEXT: [[VAL4:%.*]] = phi i32 [ 42, %[[ENTRY]] ], [ [[VAL4_NEXT:%.*]], %[[FOR_BODY]] ]93; CHECK-NEXT: [[IDX_0:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i32 [[I]]94; CHECK-NEXT: [[IDX_1:%.*]] = getelementptr inbounds nuw i32, ptr [[B]], i32 [[I]]95; CHECK-NEXT: [[IDX_2:%.*]] = getelementptr inbounds nuw i32, ptr [[C]], i32 [[I]]96; CHECK-NEXT: [[IDX_3:%.*]] = getelementptr inbounds nuw i32, ptr [[D]], i32 [[I]]97; CHECK-NEXT: [[IDX_4:%.*]] = getelementptr inbounds nuw i32, ptr [[E]], i32 [[I]]98; CHECK-NEXT: store i32 [[VAL0]], ptr [[IDX_0]], align 499; CHECK-NEXT: store i32 [[VAL1]], ptr [[IDX_1]], align 4100; CHECK-NEXT: store i32 [[VAL2]], ptr [[IDX_2]], align 4101; CHECK-NEXT: store i32 [[VAL3]], ptr [[IDX_3]], align 4102; CHECK-NEXT: store i32 [[VAL4]], ptr [[IDX_4]], align 4103; CHECK-NEXT: [[VAL0_NEXT]] = and i32 [[I]], [[J]]104; CHECK-NEXT: [[VAL1_NEXT]] = or i32 [[I]], [[J]]105; CHECK-NEXT: [[VAL2_NEXT]] = xor i32 [[I]], [[J]]106; CHECK-NEXT: [[VAL3_NEXT]] = shl i32 [[I]], [[J]]107; CHECK-NEXT: [[VAL4_NEXT]] = lshr i32 [[I]], [[J]]108; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 2109; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1110; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I_NEXT]], 10000111; CHECK-NEXT: [[EXITCOND:%.*]] = icmp slt i32 [[I_NEXT]], 10000112; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_BODY]], label %[[EXIT:.*]]113; CHECK: [[EXIT]]:114; CHECK-NEXT: ret void115;116entry:117 br label %for.body118 119for.body:120 %i = phi i32 [ 0, %entry ], [ %i.next, %for.body ]121 %j = phi i32 [ 100, %entry ] , [ %j.next, %for.body ]122 %val0 = phi i32 [ 42, %entry ], [ %val0.next, %for.body ]123 %val1 = phi i32 [ 42, %entry ], [ %val1.next, %for.body ]124 %val2 = phi i32 [ 42, %entry ], [ %val2.next, %for.body ]125 %val3 = phi i32 [ 42, %entry ], [ %val3.next, %for.body ]126 %val4 = phi i32 [ 42, %entry ], [ %val4.next, %for.body ]127 %idx.0 = getelementptr inbounds nuw i32, ptr %a, i32 %i128 %idx.1 = getelementptr inbounds nuw i32, ptr %b, i32 %i129 %idx.2 = getelementptr inbounds nuw i32, ptr %c, i32 %i130 %idx.3 = getelementptr inbounds nuw i32, ptr %d, i32 %i131 %idx.4 = getelementptr inbounds nuw i32, ptr %e, i32 %i132 store i32 %val0, ptr %idx.0, align 4133 store i32 %val1, ptr %idx.1, align 4134 store i32 %val2, ptr %idx.2, align 4135 store i32 %val3, ptr %idx.3, align 4136 store i32 %val4, ptr %idx.4, align 4137 %val0.next = and i32 %i, %j138 %val1.next = or i32 %i, %j139 %val2.next = xor i32 %i, %j140 %val3.next = shl i32 %i, %j141 %val4.next = lshr i32 %i, %j142 %i.next = add i32 %i, 2143 %j.next = add i32 %j, 1144 %cmp = icmp ne i32 %i.next, 10000145 %exitcond = icmp slt i32 %i.next, 10000146 br i1 %exitcond, label %for.body, label %exit147 148exit:149 ret void150}151