From c8ff4f94606db3d2e95e46fd3ee79985d47426b7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 20 Apr 2019 12:05:53 +0000 Subject: [PATCH] [IndVarSimplify] Generate full checks for some LFTR tests; NFC llvm-svn: 358813 --- .../IndVarSimplify/lftr-extend-const.ll | 30 ++- .../Transforms/IndVarSimplify/lftr-promote.ll | 61 +++-- test/Transforms/IndVarSimplify/lftr-reuse.ll | 208 +++++++++++++----- .../IndVarSimplify/lftr-udiv-tripcount.ll | 29 ++- test/Transforms/IndVarSimplify/lftr-zext.ll | 47 ++-- .../IndVarSimplify/lftr_disabled.ll | 40 ++-- test/Transforms/IndVarSimplify/lftr_simple.ll | 39 ++-- 7 files changed, 326 insertions(+), 128 deletions(-) diff --git a/test/Transforms/IndVarSimplify/lftr-extend-const.ll b/test/Transforms/IndVarSimplify/lftr-extend-const.ll index fa3166d4a3e..6b066a92ccd 100644 --- a/test/Transforms/IndVarSimplify/lftr-extend-const.ll +++ b/test/Transforms/IndVarSimplify/lftr-extend-const.ll @@ -1,13 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ;RUN: opt -S %s -indvars | FileCheck %s ; Provide legal integer types. target datalayout = "n8:16:32:64" -; CHECK-LABEL: @foo( -; CHECK-NOT: %lftr.wideiv = trunc i32 %indvars.iv.next to i16 -; CHECK: %exitcond = icmp ne i32 %indvars.iv.next, 512 define void @foo() #0 { +; CHECK-LABEL: @foo( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: call void @bar(i32 [[INDVARS_IV]]) #1 +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], 512 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %for.body @@ -24,9 +34,19 @@ for.end: ; preds = %for.body } ; Check that post-incrementing the backedge taken count does not overflow. -; CHECK-LABEL: @postinc( -; CHECK: icmp eq i32 %indvars.iv, 255 define i32 @postinc() #0 { +; CHECK-LABEL: @postinc( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[DO_BODY:%.*]] +; CHECK: do.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[DO_BODY]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: call void @bar(i32 [[INDVARS_IV]]) #1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[INDVARS_IV]], 255 +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1 +; CHECK-NEXT: br i1 [[CMP]], label [[DO_END:%.*]], label [[DO_BODY]] +; CHECK: do.end: +; CHECK-NEXT: ret i32 0 +; entry: br label %do.body diff --git a/test/Transforms/IndVarSimplify/lftr-promote.ll b/test/Transforms/IndVarSimplify/lftr-promote.ll index 52e1ea95af7..8d6d88e9340 100644 --- a/test/Transforms/IndVarSimplify/lftr-promote.ll +++ b/test/Transforms/IndVarSimplify/lftr-promote.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -indvars -S | FileCheck %s ; Indvars should be able to compute the exit value of this loop @@ -8,35 +9,57 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 define void @foo(double* %p, i32 %n) nounwind { ; CHECK-LABEL: @foo( -; CHECK: add -; CHECK-NOT: add +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[N:%.*]], 0 +; CHECK-NEXT: br i1 [[TMP0]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] +; CHECK: bb.nph: +; CHECK-NEXT: br label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[I_01:%.*]] = phi i32 [ [[TMP7:%.*]], [[BB3:%.*]] ], [ 0, [[BB_NPH]] ] +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[I_01]] to i64 +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr double, double* [[P:%.*]], i64 [[TMP1]] +; CHECK-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8 +; CHECK-NEXT: [[TMP4:%.*]] = fmul double [[TMP3]], 1.100000e+00 +; CHECK-NEXT: [[TMP5:%.*]] = sext i32 [[I_01]] to i64 +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr double, double* [[P]], i64 [[TMP5]] +; CHECK-NEXT: store double [[TMP4]], double* [[TMP6]], align 8 +; CHECK-NEXT: [[TMP7]] = add nuw nsw i32 [[I_01]], 1 +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i32 [[TMP7]], [[N]] +; CHECK-NEXT: br i1 [[TMP8]], label [[BB2]], label [[BB3_RETURN_CRIT_EDGE:%.*]] +; CHECK: bb3.return_crit_edge: +; CHECK-NEXT: br label [[RETURN]] +; CHECK: return: +; CHECK-NEXT: ret void +; entry: - %0 = icmp sgt i32 %n, 0 ; [#uses=1] - br i1 %0, label %bb.nph, label %return + %0 = icmp sgt i32 %n, 0 + br i1 %0, label %bb.nph, label %return bb.nph: ; preds = %entry - br label %bb2 + br label %bb2 bb2: ; preds = %bb3, %bb.nph - %i.01 = phi i32 [ %7, %bb3 ], [ 0, %bb.nph ] ; [#uses=3] - %1 = sext i32 %i.01 to i64 ; [#uses=1] - %2 = getelementptr double, double* %p, i64 %1 ; [#uses=1] - %3 = load double, double* %2, align 8 ; [#uses=1] - %4 = fmul double %3, 1.100000e+00 ; [#uses=1] - %5 = sext i32 %i.01 to i64 ; [#uses=1] - %6 = getelementptr double, double* %p, i64 %5 ; [#uses=1] - store double %4, double* %6, align 8 - %7 = add i32 %i.01, 1 ; [#uses=2] - br label %bb3 + %i.01 = phi i32 [ %7, %bb3 ], [ 0, %bb.nph ] + %1 = sext i32 %i.01 to i64 + %2 = getelementptr double, double* %p, i64 %1 + %3 = load double, double* %2, align 8 + %4 = fmul double %3, 1.100000e+00 + %5 = sext i32 %i.01 to i64 + %6 = getelementptr double, double* %p, i64 %5 + store double %4, double* %6, align 8 + %7 = add i32 %i.01, 1 + br label %bb3 bb3: ; preds = %bb2 - %8 = icmp slt i32 %7, %n ; [#uses=1] - br i1 %8, label %bb2, label %bb3.return_crit_edge + %8 = icmp slt i32 %7, %n + br i1 %8, label %bb2, label %bb3.return_crit_edge bb3.return_crit_edge: ; preds = %bb3 - br label %return + br label %return return: ; preds = %bb3.return_crit_edge, %entry - ret void + ret void } diff --git a/test/Transforms/IndVarSimplify/lftr-reuse.ll b/test/Transforms/IndVarSimplify/lftr-reuse.ll index dd09f162d79..c380f4159d5 100644 --- a/test/Transforms/IndVarSimplify/lftr-reuse.ll +++ b/test/Transforms/IndVarSimplify/lftr-reuse.ll @@ -1,5 +1,6 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -indvars -S | FileCheck %s -; + ; Make sure that indvars can perform LFTR without a canonical IV. target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -12,18 +13,36 @@ declare void @use(double %x) ; *p = p-base; ; } define void @ptriv(i8* %base, i32 %n) nounwind { +; CHECK-LABEL: @ptriv( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[N:%.*]] to i64 +; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[BASE:%.*]], i64 [[IDX_EXT]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8* [[BASE]], [[ADD_PTR]] +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] +; CHECK: for.body.preheader: +; CHECK-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8* [[BASE]], i64 [[IDX_EXT]] +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[P_02:%.*]] = phi i8* [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[BASE]], [[FOR_BODY_PREHEADER]] ] +; CHECK-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint i8* [[P_02]] to i64 +; CHECK-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint i8* [[BASE]] to i64 +; CHECK-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[SUB_PTR_SUB]] to i8 +; CHECK-NEXT: store i8 [[CONV]], i8* [[P_02]] +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8* [[P_02]], i32 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[INCDEC_PTR]], [[LFTR_LIMIT]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]] +; CHECK: for.end.loopexit: +; CHECK-NEXT: br label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: %idx.ext = sext i32 %n to i64 %add.ptr = getelementptr inbounds i8, i8* %base, i64 %idx.ext %cmp1 = icmp ult i8* %base, %add.ptr br i1 %cmp1, label %for.body, label %for.end -; CHECK: for.body: -; CHECK: phi i8* -; CHECK-NOT: phi -; CHECK-NOT: add -; CHECK: icmp ne i8* -; CHECK: br i1 for.body: %p.02 = phi i8* [ %base, %entry ], [ %incdec.ptr, %for.body ] ; cruft to make the IV useful @@ -43,13 +62,45 @@ for.end: ; This test checks that SCEVExpander can handle an outer loop that has been ; simplified, and as a result the inner loop's exit test will be rewritten. define void @expandOuterRecurrence(i32 %arg) nounwind { +; CHECK-LABEL: @expandOuterRecurrence( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 [[ARG:%.*]], 1 +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 0, [[SUB1]] +; CHECK-NEXT: br i1 [[CMP1]], label [[OUTER_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: outer.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[ARG]], -1 +; CHECK-NEXT: br label [[OUTER:%.*]] +; CHECK: outer: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[TMP0]], [[OUTER_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[OUTER_INC:%.*]] ] +; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], [[OUTER_INC]] ], [ 0, [[OUTER_PREHEADER]] ] +; CHECK-NEXT: [[SUB2:%.*]] = sub nsw i32 [[ARG]], [[I]] +; CHECK-NEXT: [[SUB3:%.*]] = sub nsw i32 [[SUB2]], 1 +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 0, [[SUB3]] +; CHECK-NEXT: br i1 [[CMP2]], label [[INNER_PH:%.*]], label [[OUTER_INC]] +; CHECK: inner.ph: +; CHECK-NEXT: br label [[INNER:%.*]] +; CHECK: inner: +; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[INNER_PH]] ], [ [[J_INC:%.*]], [[INNER]] ] +; CHECK-NEXT: [[J_INC]] = add nuw nsw i32 [[J]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[J_INC]], [[INDVARS_IV]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[INNER]], label [[OUTER_INC_LOOPEXIT:%.*]] +; CHECK: outer.inc.loopexit: +; CHECK-NEXT: br label [[OUTER_INC]] +; CHECK: outer.inc: +; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i32 [[INDVARS_IV]], -1 +; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[I_INC]], [[TMP0]] +; CHECK-NEXT: br i1 [[EXITCOND1]], label [[OUTER]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK: exit.loopexit: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: %sub1 = sub nsw i32 %arg, 1 %cmp1 = icmp slt i32 0, %sub1 br i1 %cmp1, label %outer, label %exit -; CHECK: outer: -; CHECK: icmp slt outer: %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ] %sub2 = sub nsw i32 %arg, %i @@ -60,17 +111,12 @@ outer: inner.ph: br label %inner -; CHECK: inner: -; CHECK: br i1 inner: %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ] %j.inc = add nsw i32 %j, 1 %cmp3 = icmp slt i32 %j.inc, %sub3 br i1 %cmp3, label %inner, label %outer.inc -; CHECK: outer.inc: -; CHECK: icmp ne -; CHECK: br i1 outer.inc: %i.inc = add nsw i32 %i, 1 %cmp4 = icmp slt i32 %i.inc, %sub1 @@ -83,16 +129,34 @@ exit: ; Force SCEVExpander to look for an existing well-formed phi. ; Perform LFTR without generating extra preheader code. define void @guardedloop([0 x double]* %matrix, [0 x double]* %vector, - i32 %irow, i32 %ilead) nounwind { -; CHECK: entry: -; CHECK-NOT: zext -; CHECK-NOT: add -; CHECK: loop: -; CHECK: phi i64 -; CHECK: phi i64 -; CHECK-NOT: phi -; CHECK: icmp ne -; CHECK: br i1 +; CHECK-LABEL: @guardedloop( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[IROW:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_PREHEADER:%.*]], label [[RETURN:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ILEAD:%.*]] to i64 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ 0, [[LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], [[INDVARS_IV2]] +; CHECK-NEXT: [[MATRIXP:%.*]] = getelementptr inbounds [0 x double], [0 x double]* [[MATRIX:%.*]], i32 0, i64 [[TMP1]] +; CHECK-NEXT: [[V1:%.*]] = load double, double* [[MATRIXP]] +; CHECK-NEXT: call void @use(double [[V1]]) +; CHECK-NEXT: [[VECTORP:%.*]] = getelementptr inbounds [0 x double], [0 x double]* [[VECTOR:%.*]], i32 0, i64 [[INDVARS_IV2]] +; CHECK-NEXT: [[V2:%.*]] = load double, double* [[VECTORP]] +; CHECK-NEXT: call void @use(double [[V2]]) +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[TMP0]] +; CHECK-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 +; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[IROW]] to i64 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], [[WIDE_TRIP_COUNT]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[RETURN_LOOPEXIT:%.*]] +; CHECK: return.loopexit: +; CHECK-NEXT: br label [[RETURN]] +; CHECK: return: +; CHECK-NEXT: ret void +; + i32 %irow, i32 %ilead) nounwind { entry: %cmp = icmp slt i32 1, %irow br i1 %cmp, label %loop, label %return @@ -120,18 +184,22 @@ return: ; Avoid generating extra code to materialize a trip count. Skip LFTR. define void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector, - i32 %irow, i32 %ilead) nounwind { +; CHECK-LABEL: @unguardedloop( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[IROW:%.*]] to i64 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 +; CHECK-NEXT: [[CMP196:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT3]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP196]], label [[LOOP]], label [[RETURN:%.*]] +; CHECK: return: +; CHECK-NEXT: ret void +; + i32 %irow, i32 %ilead) nounwind { entry: br label %loop -; CHECK: entry: -; CHECK-NOT: zext -; CHECK-NOT: add -; CHECK: loop: -; CHECK: phi i64 -; CHECK-NOT: phi -; CHECK: icmp slt -; CHECK: br i1 loop: %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ] %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ] @@ -158,6 +226,30 @@ return: ; TODO: Fix for PR13371 currently makes this impossible. See ; IndVarSimplify.cpp hasConcreteDef(). We may want to change to undef rules. define void @geplftr(i8* %base, i32 %x, i32 %y, i32 %n) nounwind { +; CHECK-LABEL: @geplftr( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X_EXT:%.*]] = sext i32 [[X:%.*]] to i64 +; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[BASE:%.*]], i64 [[X_EXT]] +; CHECK-NEXT: [[Y_EXT:%.*]] = sext i32 [[Y:%.*]] to i64 +; CHECK-NEXT: [[ADD_PTR10:%.*]] = getelementptr inbounds i8, i8* [[ADD_PTR]], i64 [[Y_EXT]] +; CHECK-NEXT: [[LIM:%.*]] = add i32 [[X]], [[N:%.*]] +; CHECK-NEXT: [[CMP_PH:%.*]] = icmp ult i32 [[X]], [[LIM]] +; CHECK-NEXT: br i1 [[CMP_PH]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INC:%.*]], [[LOOP]] ], [ [[X]], [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[APTR:%.*]] = phi i8* [ [[INCDEC_PTR:%.*]], [[LOOP]] ], [ [[ADD_PTR10]], [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8* [[APTR]], i32 1 +; CHECK-NEXT: store i8 3, i8* [[APTR]] +; CHECK-NEXT: [[INC]] = add nuw i32 [[I]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], [[LIM]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK: exit.loopexit: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: %x.ext = sext i32 %x to i64 %add.ptr = getelementptr inbounds i8, i8* %base, i64 %x.ext @@ -166,14 +258,6 @@ entry: %lim = add i32 %x, %n %cmp.ph = icmp ult i32 %x, %lim br i1 %cmp.ph, label %loop, label %exit -; CHECK-LABEL: @geplftr( -; CHECK: loop: -; CHECK: phi i8* -; DISABLE-NOT: phi // This check is currently disabled -; CHECK: getelementptr -; CHECK: store -; DISABLE: icmp ne i8* // This check is currently disabled -; CHECK: br i1 loop: %i = phi i32 [ %x, %entry ], [ %inc, %loop ] %aptr = phi i8* [ %add.ptr10, %entry ], [ %incdec.ptr, %loop ] @@ -189,14 +273,16 @@ exit: ; Exercise backedge taken count verification with a never-taken loop. define void @nevertaken() nounwind uwtable ssp { +; CHECK-LABEL: @nevertaken( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: br label %loop -; CHECK-LABEL: @nevertaken( -; CHECK: loop: -; CHECK-NOT: phi -; CHECK-NOT: add -; CHECK-NOT: icmp -; CHECK: exit: loop: %i = phi i32 [ 0, %entry ], [ %inc, %loop ] %inc = add nsw i32 %i, 1 @@ -209,19 +295,33 @@ exit: ; Test LFTR on an IV whose recurrence start is a non-unit pointer type. define void @aryptriv([256 x i8]* %base, i32 %n) nounwind { +; CHECK-LABEL: @aryptriv( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[IVSTART:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[BASE:%.*]], i32 0, i32 0 +; CHECK-NEXT: [[IVEND:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[BASE]], i32 0, i32 [[N:%.*]] +; CHECK-NEXT: [[CMP_PH:%.*]] = icmp ult i8* [[IVSTART]], [[IVEND]] +; CHECK-NEXT: br i1 [[CMP_PH]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[N]] to i64 +; CHECK-NEXT: [[LFTR_LIMIT:%.*]] = getelementptr i8, i8* [[IVSTART]], i64 [[TMP0]] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[APTR:%.*]] = phi i8* [ [[INCDEC_PTR:%.*]], [[LOOP]] ], [ [[IVSTART]], [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8* [[APTR]], i32 1 +; CHECK-NEXT: store i8 3, i8* [[APTR]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[INCDEC_PTR]], [[LFTR_LIMIT]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK: exit.loopexit: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: %ivstart = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 0 %ivend = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 %n %cmp.ph = icmp ult i8* %ivstart, %ivend br i1 %cmp.ph, label %loop, label %exit -; CHECK: loop: -; CHECK: phi i8* -; CHECK-NOT: phi -; CHECK: getelementptr -; CHECK: store -; CHECK: icmp ne i8* -; CHECK: br i1 loop: %aptr = phi i8* [ %ivstart, %entry ], [ %incdec.ptr, %loop ] %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1 diff --git a/test/Transforms/IndVarSimplify/lftr-udiv-tripcount.ll b/test/Transforms/IndVarSimplify/lftr-udiv-tripcount.ll index 8a1bb07bb0c..371b8e58c23 100644 --- a/test/Transforms/IndVarSimplify/lftr-udiv-tripcount.ll +++ b/test/Transforms/IndVarSimplify/lftr-udiv-tripcount.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -indvars -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" @@ -8,22 +9,38 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 define void @foo(i8* %a, i8 %n) nounwind uwtable ssp { ; CHECK-LABEL: @foo( - entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: [[E:%.*]] = icmp sgt i8 [[N:%.*]], 3 +; CHECK-NEXT: br i1 [[E]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N]], 3 +; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[TMP0]], 2 +; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], 1 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[I1:%.*]] = phi i8 [ [[I1_INC:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[I1_INC]] = add nuw nsw i8 [[I1]], 1 +; CHECK-NEXT: store volatile i8 0, i8* [[A:%.*]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 [[I1_INC]], [[TMP2]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK: exit.loopexit: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: %e = icmp sgt i8 %n, 3 br i1 %e, label %loop, label %exit - loop: -; CHECK-LABEL: loop: +loop: %i = phi i8 [ 0, %entry ], [ %i.inc, %loop ] %i1 = phi i8 [ 0, %entry ], [ %i1.inc, %loop ] %i.inc = add nsw i8 %i, 4 %i1.inc = add i8 %i1, 1 store volatile i8 0, i8* %a %c = icmp slt i8 %i, %n -; CHECK-LABEL: %exitcond = icmp ne i8 %i1.inc br i1 %c, label %loop, label %exit - exit: -; CHECK-LABEL: exit: +exit: ret void } diff --git a/test/Transforms/IndVarSimplify/lftr-zext.ll b/test/Transforms/IndVarSimplify/lftr-zext.ll index e654e143cee..0e49bac550b 100644 --- a/test/Transforms/IndVarSimplify/lftr-zext.ll +++ b/test/Transforms/IndVarSimplify/lftr-zext.ll @@ -1,26 +1,41 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -indvars -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.9.0" @data = common global [240 x i8] zeroinitializer, align 16 -define void @foo(i8* %a) nounwind uwtable ssp { -; CHECK: %exitcond -; CHECK-NOT: ([240 x i8]* @data, i64 0, i64 -16) - br label %1 +define void @foo(i8* %a) #0 { +; CHECK-LABEL: @foo( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[P_0:%.*]] = phi i8* [ getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[DOT0:%.*]] = phi i8* [ [[A:%.*]], [[ENTRY]] ], [ [[TMP:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP]] = getelementptr inbounds i8, i8* [[DOT0]], i64 1 +; CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[DOT0]], align 1 +; CHECK-NEXT: [[TMP3]] = getelementptr inbounds i8, i8* [[P_0]], i64 1 +; CHECK-NEXT: store i8 [[TMP2]], i8* [[P_0]], align 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[TMP3]], getelementptr (i8, i8* getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), i64 240) +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + br label %loop -;