brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · e24eeef Raw
200 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Check that phi analysis can determine the number of iterations of the3; loop to peel such that the phi nodes (other than the iteration variable)4; have their resulting values known and are thus removed by peeling the loop5; at least that many times.6 7; RUN: opt < %s -S -passes=loop-unroll | FileCheck %s8; RUN: opt < %s -S -passes=loop-unroll-full | FileCheck %s9 10; void f(float);11; void g(int);12declare void @_Z1ff(float)13declare void @_Z1gi(i32 signext)14 15; Check that phi analysis can handle a cast.16define void @_Z8castTestv() {17; The phis become invariant through the chain of phis, with a unary18; instruction on a loop invariant.  Check that the phis for x, a, and y19; are removed since x is based on a cast of y, which is based on a, which is20; set on the backedge.21; Consider the calls to g and f.22; First iteration: g(0), x=0, f(0.0), y=0.0, a=5.023; Second iteration: g(0), x=0, f(0.0), y=5.0, a=5.024; Third iteration: g(0), x=5 (requires cast), f(5.0), a=5.025; Fourth iteration (and subsequent): g(5), x=5, f(5.0), a=5.026; Therefore, peeling 3 times removes the phi nodes, so check for 3 peels.27;28; void castTest() {29;   int x = 0;30;   float y = 0.0;31;   float a = 0.0;32;   for(int i = 0; i <100000; ++i) {33;     g(x);34;     x = y;35;     f(y);36;     y = a;37;     a = 5.0;38;   }39; }40;41; CHECK-LABEL: @_Z8castTestv(42; CHECK-NEXT:  entry:43; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]44; CHECK:       for.body.peel.begin:45; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]46; CHECK:       for.body.peel:47; CHECK-NEXT:    tail call void @_Z1gi(i32 noundef signext 0)48; CHECK-NEXT:    [[CONV_PEEL:%.*]] = fptosi float 0.000000e+00 to i3249; CHECK-NEXT:    tail call void @_Z1ff(float noundef 0.000000e+00)50; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 151; CHECK-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp ne i32 [[INC_PEEL]], 10000052; CHECK-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_COND_CLEANUP:%.*]]53; CHECK:       for.body.peel.next:54; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]55; CHECK:       for.body.peel2:56; CHECK-NEXT:    tail call void @_Z1gi(i32 noundef signext [[CONV_PEEL]])57; CHECK-NEXT:    [[CONV_PEEL3:%.*]] = fptosi float 0.000000e+00 to i3258; CHECK-NEXT:    tail call void @_Z1ff(float noundef 0.000000e+00)59; CHECK-NEXT:    [[INC_PEEL4:%.*]] = add nuw nsw i32 [[INC_PEEL]], 160; CHECK-NEXT:    [[EXITCOND_PEEL5:%.*]] = icmp ne i32 [[INC_PEEL4]], 10000061; CHECK-NEXT:    br i1 [[EXITCOND_PEEL5]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_COND_CLEANUP]]62; CHECK:       for.body.peel.next1:63; CHECK-NEXT:    br label [[FOR_BODY_PEEL7:%.*]]64; CHECK:       for.body.peel7:65; CHECK-NEXT:    tail call void @_Z1gi(i32 noundef signext [[CONV_PEEL3]])66; CHECK-NEXT:    [[CONV_PEEL8:%.*]] = fptosi float 5.000000e+00 to i3267; CHECK-NEXT:    tail call void @_Z1ff(float noundef 5.000000e+00)68; CHECK-NEXT:    [[INC_PEEL9:%.*]] = add nuw nsw i32 [[INC_PEEL4]], 169; CHECK-NEXT:    [[EXITCOND_PEEL10:%.*]] = icmp ne i32 [[INC_PEEL9]], 10000070; CHECK-NEXT:    br i1 [[EXITCOND_PEEL10]], label [[FOR_BODY_PEEL_NEXT6:%.*]], label [[FOR_COND_CLEANUP]]71; CHECK:       for.body.peel.next6:72; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT11:%.*]]73; CHECK:       for.body.peel.next11:74; CHECK-NEXT:    br label [[ENTRY_PEEL_NEWPH:%.*]]75; CHECK:       entry.peel.newph:76; CHECK-NEXT:    br label [[FOR_BODY:%.*]]77; CHECK:       for.cond.cleanup.loopexit:78; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]79; CHECK:       for.cond.cleanup:80; CHECK-NEXT:    ret void81; CHECK:       for.body:82; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INC_PEEL9]], [[ENTRY_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]83; CHECK-NEXT:    [[X:%.*]] = phi i32 [ [[CONV_PEEL8]], [[ENTRY_PEEL_NEWPH]] ], [ 5, [[FOR_BODY]] ]84; CHECK-NEXT:    tail call void @_Z1gi(i32 noundef signext [[X]])85; CHECK-NEXT:    tail call void @_Z1ff(float noundef 5.000000e+00)86; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I]], 187; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[INC]], 10000088; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]89;90entry:91  br label %for.body92 93for.cond.cleanup:94  ret void95 96for.body:97  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]98  %a = phi float [ 0.000000e+00, %entry ], [ 5.000000e+00, %for.body ]99  %y = phi float [ 0.000000e+00, %entry ], [ %a, %for.body ]100  %x = phi i32 [ 0, %entry ], [ %conv, %for.body ]101  tail call void @_Z1gi(i32 noundef signext %x)102  %conv = fptosi float %y to i32103  tail call void @_Z1ff(float noundef %y)104  %inc = add nuw nsw i32 %i, 1105  %exitcond = icmp ne i32 %inc, 100000106  br i1 %exitcond, label %for.body, label %for.cond.cleanup107}108 109; Check that phi analysis can handle a binary operator.110define void @_Z6binaryv() {111; The phis become invariant through the chain of phis, with a unary112; instruction on a loop invariant.  Check that the phis for x, a, and y113; are removed since x is based on y, which is based on a, which is based114; on a binary add of a phi and a constant.115; Consider the calls to g:116; First iteration: g(0), x=0, g(0), y=1, a=5117; Second iteration: g(0), x=1, g(5), y=6(binary operator), a=5118; Third iteration: g(1), x=6, g(5), y=6, a=5119; Fourth iteration (and subsequent): g(6), x=6, g(5), y=6, a=5120; Therefore, peeling 3 times removes the phi nodes.121;122; void g(int);123; void binary() {124;   int x = 0;125;   int y = 0;126;   int a = 0;127;   for(int i = 0; i <100000; ++i) {128;     g(x);129;     x = y;130;     g(a);131;     y = a + 1;132;     a = 5;133;   }134; }135;136; CHECK-LABEL: @_Z6binaryv(137; CHECK-NEXT:  entry:138; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]139; CHECK:       for.body.peel.begin:140; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]141; CHECK:       for.body.peel:142; CHECK-NEXT:    tail call void @_Z1gi(i32 signext 0)143; CHECK-NEXT:    tail call void @_Z1gi(i32 signext 0)144; CHECK-NEXT:    [[ADD_PEEL:%.*]] = add nuw nsw i32 0, 1145; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 1146; CHECK-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], 100000147; CHECK-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]148; CHECK:       for.body.peel.next:149; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]150; CHECK:       for.body.peel2:151; CHECK-NEXT:    tail call void @_Z1gi(i32 signext 0)152; CHECK-NEXT:    tail call void @_Z1gi(i32 signext 5)153; CHECK-NEXT:    [[INC_PEEL4:%.*]] = add nuw nsw i32 [[INC_PEEL]], 1154; CHECK-NEXT:    [[EXITCOND_PEEL5:%.*]] = icmp eq i32 [[INC_PEEL4]], 100000155; CHECK-NEXT:    br i1 [[EXITCOND_PEEL5]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY_PEEL_NEXT1:%.*]]156; CHECK:       for.body.peel.next1:157; CHECK-NEXT:    br label [[FOR_BODY_PEEL7:%.*]]158; CHECK:       for.body.peel7:159; CHECK-NEXT:    tail call void @_Z1gi(i32 signext [[ADD_PEEL]])160; CHECK-NEXT:    tail call void @_Z1gi(i32 signext 5)161; CHECK-NEXT:    [[INC_PEEL9:%.*]] = add nuw nsw i32 [[INC_PEEL4]], 1162; CHECK-NEXT:    [[EXITCOND_PEEL10:%.*]] = icmp eq i32 [[INC_PEEL9]], 100000163; CHECK-NEXT:    br i1 [[EXITCOND_PEEL10]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY_PEEL_NEXT6:%.*]]164; CHECK:       for.body.peel.next6:165; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT11:%.*]]166; CHECK:       for.body.peel.next11:167; CHECK-NEXT:    br label [[ENTRY_PEEL_NEWPH:%.*]]168; CHECK:       entry.peel.newph:169; CHECK-NEXT:    br label [[FOR_BODY:%.*]]170; CHECK:       for.cond.cleanup.loopexit:171; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]172; CHECK:       for.cond.cleanup:173; CHECK-NEXT:    ret void174; CHECK:       for.body:175; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INC_PEEL9]], [[ENTRY_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]176; CHECK-NEXT:    tail call void @_Z1gi(i32 signext 6)177; CHECK-NEXT:    tail call void @_Z1gi(i32 signext 5)178; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I]], 1179; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 100000180; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]]181;182entry:183  br label %for.body184 185for.cond.cleanup:186  ret void187 188for.body:189  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]190  %a = phi i32 [ 0, %entry ], [ 5, %for.body ]191  %y = phi i32 [ 0, %entry ], [ %add, %for.body ]192  %x = phi i32 [ 0, %entry ], [ %y, %for.body ]193  tail call void @_Z1gi(i32 signext %x)194  tail call void @_Z1gi(i32 signext %a)195  %add = add nuw nsw i32 %a, 1196  %inc = add nuw nsw i32 %i, 1197  %exitcond = icmp eq i32 %inc, 100000198  br i1 %exitcond, label %for.cond.cleanup, label %for.body199}200