From 9bf8fcc900ab767eab882ad74af9e86a5c014e2c Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Mon, 27 Jan 2020 23:22:30 +0300 Subject: [PATCH] [NFC][IndVarSimplify] Autogenerate tests affected by isHighCostExpansionHelper() cost modelling (PR44668) --- test/Analysis/ScalarEvolution/pr28705.ll | 41 --- .../IndVarSimplify/dont-recompute.ll | 137 ++++++-- test/Transforms/IndVarSimplify/lftr-reuse.ll | 2 + .../loop-invariant-conditions.ll | 315 +++++++++++++++--- .../IndVarSimplify/lrev-existing-umin.ll | 61 +++- test/Transforms/IndVarSimplify/pr28705.ll | 65 ++++ .../IndVarSimplify/widen-loop-comp.ll | 302 +++++++++++++---- 7 files changed, 732 insertions(+), 191 deletions(-) delete mode 100644 test/Analysis/ScalarEvolution/pr28705.ll create mode 100644 test/Transforms/IndVarSimplify/pr28705.ll diff --git a/test/Analysis/ScalarEvolution/pr28705.ll b/test/Analysis/ScalarEvolution/pr28705.ll deleted file mode 100644 index 9a8487a6c66..00000000000 --- a/test/Analysis/ScalarEvolution/pr28705.ll +++ /dev/null @@ -1,41 +0,0 @@ -; PR28705 -; RUN: opt < %s -indvars -S | FileCheck %s - -; Check IndVarSimplify doesn't replace external use of the induction var -; "%inc.i.i" with "%.sroa.speculated + 1" because it is not profitable. -; -; CHECK-LABEL: @foo( -; CHECK: %[[EXIT:.+]] = phi i32 [ %inc.i.i, %for.body650 ] -; CHECK: %DB.sroa.9.0.lcssa = phi i32 [ 1, %entry ], [ %[[EXIT]], %loopexit ] -; -define void @foo(i32 %sub.ptr.div.i, i8* %ref.i1174) local_unnamed_addr { -entry: - %cmp.i1137 = icmp ugt i32 %sub.ptr.div.i, 3 - %.sroa.speculated = select i1 %cmp.i1137, i32 3, i32 %sub.ptr.div.i - %cmp6483126 = icmp eq i32 %.sroa.speculated, 0 - br i1 %cmp6483126, label %XZ.exit, label %for.body650.lr.ph - -for.body650.lr.ph: - br label %for.body650 - -loopexit: - %inc.i.i.lcssa = phi i32 [ %inc.i.i, %for.body650 ] - br label %XZ.exit - -XZ.exit: - %DB.sroa.9.0.lcssa = phi i32 [ 1, %entry ], [ %inc.i.i.lcssa, %loopexit ] - br label %end - -for.body650: - %iv = phi i32 [ 0, %for.body650.lr.ph ], [ %inc655, %for.body650 ] - %iv2 = phi i32 [ 1, %for.body650.lr.ph ], [ %inc.i.i, %for.body650 ] - %arrayidx.i.i1105 = getelementptr inbounds i8, i8* %ref.i1174, i32 %iv2 - store i8 7, i8* %arrayidx.i.i1105, align 1 - %inc.i.i = add i32 %iv2, 1 - %inc655 = add i32 %iv, 1 - %cmp648 = icmp eq i32 %inc655, %.sroa.speculated - br i1 %cmp648, label %loopexit, label %for.body650 - -end: - ret void -} diff --git a/test/Transforms/IndVarSimplify/dont-recompute.ll b/test/Transforms/IndVarSimplify/dont-recompute.ll index 22087710a9c..e31c5827123 100644 --- a/test/Transforms/IndVarSimplify/dont-recompute.ll +++ b/test/Transforms/IndVarSimplify/dont-recompute.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -indvars -S | FileCheck %s ; This tests that the IV is not recomputed outside of the loop when it is known @@ -21,8 +22,23 @@ declare void @func(i32) -; CHECK-LABEL: @test( define void @test(i32 %m) nounwind uwtable { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] +; CHECK-NEXT: tail call void @func(i32 [[ADD]]) +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] +; CHECK: for.end: +; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) +; CHECK-NEXT: ret void +; entry: br label %for.body @@ -30,23 +46,32 @@ for.body: ; preds = %for.body, %entry %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] %add = add i32 %a.05, %m -; CHECK: tail call void @func(i32 %add) tail call void @func(i32 %add) %inc = add nsw i32 %i.06, 1 %exitcond = icmp eq i32 %inc, 186 br i1 %exitcond, label %for.end, label %for.body for.end: ; preds = %for.body -; CHECK: for.end: -; CHECK-NOT: mul i32 %m, 186 -; CHECK:%add.lcssa = phi i32 [ %add, %for.body ] -; CHECK-NEXT: tail call void @func(i32 %add.lcssa) tail call void @func(i32 %add) ret void } -; CHECK-LABEL: @test2( define i32 @test2(i32 %m) nounwind uwtable { +; CHECK-LABEL: @test2( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] +; CHECK-NEXT: tail call void @func(i32 [[ADD]]) +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] +; CHECK: for.end: +; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] +; CHECK-NEXT: ret i32 [[ADD_LCSSA]] +; entry: br label %for.body @@ -54,22 +79,32 @@ for.body: ; preds = %for.body, %entry %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] %add = add i32 %a.05, %m -; CHECK: tail call void @func(i32 %add) tail call void @func(i32 %add) %inc = add nsw i32 %i.06, 1 %exitcond = icmp eq i32 %inc, 186 br i1 %exitcond, label %for.end, label %for.body for.end: ; preds = %for.body -; CHECK: for.end: -; CHECK-NOT: mul i32 %m, 186 -; CHECK:%add.lcssa = phi i32 [ %add, %for.body ] -; CHECK-NEXT: ret i32 %add.lcssa ret i32 %add } -; CHECK-LABEL: @test3( define void @test3(i32 %m) nounwind uwtable { +; CHECK-LABEL: @test3( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] +; CHECK-NEXT: tail call void @func(i32 [[ADD]]) +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] +; CHECK: for.end: +; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) +; CHECK-NEXT: ret void +; entry: br label %for.body @@ -83,23 +118,34 @@ for.body: ; preds = %for.body, %entry mul i32 %add, 1 mul i32 %add, 1 mul i32 %add, 1 -; CHECK: tail call void @func(i32 %add) tail call void @func(i32 %add) %inc = add nsw i32 %i.06, 1 %exitcond = icmp eq i32 %inc, 186 br i1 %exitcond, label %for.end, label %for.body for.end: ; preds = %for.body -; CHECK: for.end: -; CHECK-NOT: mul i32 %m, 186 -; CHECK:%add.lcssa = phi i32 [ %add, %for.body ] -; CHECK-NEXT: tail call void @func(i32 %add.lcssa) tail call void @func(i32 %add) ret void } -; CHECK-LABEL: @test4( define void @test4(i32 %m) nounwind uwtable { +; CHECK-LABEL: @test4( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] +; CHECK-NEXT: tail call void @func(i32 [[ADD]]) +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] +; CHECK: for.end: +; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] +; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[ADD_LCSSA]], 123 +; CHECK-NEXT: tail call void @func(i32 [[SOFT_USE]]) +; CHECK-NEXT: ret void +; entry: br label %for.body @@ -107,25 +153,35 @@ for.body: ; preds = %for.body, %entry %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] %add = add i32 %a.05, %m -; CHECK: tail call void @func(i32 %add) tail call void @func(i32 %add) %inc = add nsw i32 %i.06, 1 %exitcond = icmp eq i32 %inc, 186 br i1 %exitcond, label %for.end, label %for.body for.end: ; preds = %for.body -; CHECK: for.end: -; CHECK-NOT: mul i32 %m, 186 -; CHECK:%add.lcssa = phi i32 [ %add, %for.body ] -; CHECK-NEXT: %soft_use = add i32 %add.lcssa, 123 -; CHECK-NEXT: tail call void @func(i32 %soft_use) %soft_use = add i32 %add, 123 tail call void @func(i32 %soft_use) ret void } -; CHECK-LABEL: @test5( define void @test5(i32 %m) nounwind uwtable { +; CHECK-LABEL: @test5( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] +; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[ADD]], 123 +; CHECK-NEXT: tail call void @func(i32 [[SOFT_USE]]) +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] +; CHECK: for.end: +; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) +; CHECK-NEXT: ret void +; entry: br label %for.body @@ -134,23 +190,35 @@ for.body: ; preds = %for.body, %entry %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] %add = add i32 %a.05, %m %soft_use = add i32 %add, 123 -; CHECK: tail call void @func(i32 %soft_use) tail call void @func(i32 %soft_use) %inc = add nsw i32 %i.06, 1 %exitcond = icmp eq i32 %inc, 186 br i1 %exitcond, label %for.end, label %for.body for.end: ; preds = %for.body -; CHECK: for.end: -; CHECK-NOT: mul i32 %m, 186 -; CHECK:%add.lcssa = phi i32 [ %add, %for.body ] -; CHECK-NEXT: tail call void @func(i32 %add.lcssa) tail call void @func(i32 %add) ret void } -; CHECK-LABEL: @test6( define void @test6(i32 %m, i32* %p) nounwind uwtable { +; CHECK-LABEL: @test6( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] +; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[ADD]], 123 +; CHECK-NEXT: [[PIDX:%.*]] = getelementptr i32, i32* [[P:%.*]], i32 [[ADD]] +; CHECK-NEXT: store i32 [[SOFT_USE]], i32* [[PIDX]] +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] +; CHECK: for.end: +; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) +; CHECK-NEXT: ret void +; entry: br label %for.body @@ -159,7 +227,6 @@ for.body: ; preds = %for.body, %entry %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] %add = add i32 %a.05, %m %soft_use = add i32 %add, 123 -; CHECK: store i32 %soft_use, i32* %pidx %pidx = getelementptr i32, i32* %p, i32 %add store i32 %soft_use, i32* %pidx %inc = add nsw i32 %i.06, 1 @@ -167,10 +234,6 @@ for.body: ; preds = %for.body, %entry br i1 %exitcond, label %for.end, label %for.body for.end: ; preds = %for.body -; CHECK: for.end: -; CHECK-NOT: mul i32 %m, 186 -; CHECK:%add.lcssa = phi i32 [ %add, %for.body ] -; CHECK-NEXT: tail call void @func(i32 %add.lcssa) tail call void @func(i32 %add) ret void } diff --git a/test/Transforms/IndVarSimplify/lftr-reuse.ll b/test/Transforms/IndVarSimplify/lftr-reuse.ll index 2053d70fbc1..ba1fba9187e 100644 --- a/test/Transforms/IndVarSimplify/lftr-reuse.ll +++ b/test/Transforms/IndVarSimplify/lftr-reuse.ll @@ -128,6 +128,7 @@ 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, +; ; CHECK-LABEL: @guardedloop( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[IROW:%.*]] @@ -183,6 +184,7 @@ return: ; Avoid generating extra code to materialize a trip count. Skip LFTR. define void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector, +; ; CHECK-LABEL: @unguardedloop( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[IROW:%.*]] to i64 diff --git a/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll b/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll index f5b80d3688d..e2229609798 100644 --- a/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll +++ b/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll @@ -1,16 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -indvars -indvars-predicate-loops=0 %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" define void @test1(i64 %start) { -; CHECK-LABEL: @test1 +; CHECK-LABEL: @test1( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop loop: %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] %indvars.iv.next = add nsw i64 %indvars.iv, 1 -; CHECK: %cmp1 = icmp slt i64 %start, -1 %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %loop @@ -19,14 +27,21 @@ for.end: ; preds = %if.end, %entry } define void @test2(i64 %start) { -; CHECK-LABEL: @test2 +; CHECK-LABEL: @test2( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[CMP1:%.*]] = icmp sle i64 [[START:%.*]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop loop: %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] %indvars.iv.next = add nsw i64 %indvars.iv, 1 -; CHECK: %cmp1 = icmp sle i64 %start, -1 %cmp1 = icmp sle i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %loop @@ -36,7 +51,21 @@ for.end: ; preds = %if.end, %entry ; As long as the test dominates the backedge, we're good define void @test3(i64 %start) { -; CHECK-LABEL: @test3 +; CHECK-LABEL: @test3( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK: backedge: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop @@ -48,8 +77,7 @@ loop: backedge: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() -; CHECK: %cmp1 = icmp slt i64 %start, -1 + call void @foo() %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %loop @@ -58,7 +86,21 @@ for.end: ; preds = %if.end, %entry } define void @test4(i64 %start) { -; CHECK-LABEL: @test4 +; CHECK-LABEL: @test4( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK: backedge: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[START]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop @@ -70,8 +112,7 @@ loop: backedge: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() -; CHECK: %cmp1 = icmp sgt i64 %start, -1 + call void @foo() %cmp1 = icmp sgt i64 %indvars.iv, -1 br i1 %cmp1, label %loop, label %for.end @@ -80,7 +121,21 @@ for.end: ; preds = %if.end, %entry } define void @test5(i64 %start) { -; CHECK-LABEL: @test5 +; CHECK-LABEL: @test5( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK: backedge: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[START]], 100 +; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop @@ -92,8 +147,7 @@ loop: backedge: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() -; CHECK: %cmp1 = icmp ugt i64 %start, 100 + call void @foo() %cmp1 = icmp ugt i64 %indvars.iv, 100 br i1 %cmp1, label %loop, label %for.end @@ -102,7 +156,21 @@ for.end: ; preds = %if.end, %entry } define void @test6(i64 %start) { -; CHECK-LABEL: @test6 +; CHECK-LABEL: @test6( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK: backedge: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[START]], 100 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop @@ -114,8 +182,7 @@ loop: backedge: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() -; CHECK: %cmp1 = icmp ult i64 %start, 100 + call void @foo() %cmp1 = icmp ult i64 %indvars.iv, 100 br i1 %cmp1, label %for.end, label %loop @@ -124,7 +191,21 @@ for.end: ; preds = %if.end, %entry } define void @test7(i64 %start, i64* %inc_ptr) { -; CHECK-LABEL: @test7 +; CHECK-LABEL: @test7( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !0 +; CHECK-NEXT: [[OK:%.*]] = icmp sge i64 [[INC]], 0 +; CHECK-NEXT: br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END_LOOPEXIT:%.*]], label [[LOOP]] +; CHECK: for.end.loopexit: +; CHECK-NEXT: br label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: %inc = load i64, i64* %inc_ptr, !range !0 %ok = icmp sge i64 %inc, 0 @@ -133,7 +214,6 @@ entry: loop: %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] %indvars.iv.next = add nsw i64 %indvars.iv, %inc -; CHECK: %cmp1 = icmp slt i64 %start, -1 %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %loop @@ -144,7 +224,24 @@ for.end: ; preds = %if.end, %entry ; Negative test - we can't show that the internal branch executes, so we can't ; fold the test to a loop invariant one. define void @test1_neg(i64 %start) { -; CHECK-LABEL: @test1_neg +; CHECK-LABEL: @test1_neg( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[SKIP:%.*]] +; CHECK: skip: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop @@ -155,13 +252,12 @@ loop: br i1 %cmp, label %backedge, label %skip skip: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() -; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 + call void @foo() %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %backedge backedge: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() + call void @foo() br label %loop for.end: ; preds = %if.end, %entry @@ -169,9 +265,26 @@ for.end: ; preds = %if.end, %entry } ; Slightly subtle version of @test4 where the icmp dominates the backedge, -; but the exit branch doesn't. +; but the exit branch doesn't. define void @test2_neg(i64 %start) { -; CHECK-LABEL: @test2_neg +; CHECK-LABEL: @test2_neg( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[SKIP:%.*]] +; CHECK: skip: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop @@ -179,16 +292,15 @@ loop: %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] %indvars.iv.next = add nsw i64 %indvars.iv, 1 %cmp = icmp eq i64 %indvars.iv.next, 25 -; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp, label %backedge, label %skip skip: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() + call void @foo() br i1 %cmp1, label %for.end, label %backedge backedge: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() + call void @foo() br label %loop for.end: ; preds = %if.end, %entry @@ -197,14 +309,23 @@ for.end: ; preds = %if.end, %entry ; The branch has to exit the loop if the condition is true define void @test3_neg(i64 %start) { -; CHECK-LABEL: @test3_neg +; CHECK-LABEL: @test3_neg( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop loop: %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] %indvars.iv.next = add nsw i64 %indvars.iv, 1 -; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %loop, label %for.end @@ -213,7 +334,21 @@ for.end: ; preds = %if.end, %entry } define void @test4_neg(i64 %start) { -; CHECK-LABEL: @test4_neg +; CHECK-LABEL: @test4_neg( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK: backedge: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop @@ -225,8 +360,7 @@ loop: backedge: ; prevent flattening, needed to make sure we're testing what we intend - call void @foo() -; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1 + call void @foo() %cmp1 = icmp sgt i64 %indvars.iv, -1 ; %cmp1 can be made loop invariant only if the branch below goes to @@ -238,14 +372,23 @@ for.end: ; preds = %if.end, %entry } define void @test5_neg(i64 %start, i64 %inc) { -; CHECK-LABEL: @test5_neg +; CHECK-LABEL: @test5_neg( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[INC:%.*]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br label %loop loop: %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] %indvars.iv.next = add nsw i64 %indvars.iv, %inc -; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %loop @@ -254,7 +397,23 @@ for.end: ; preds = %if.end, %entry } define void @test8(i64 %start, i64* %inc_ptr) { -; CHECK-LABEL: @test8 +; CHECK-LABEL: @test8( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !1 +; CHECK-NEXT: [[OK:%.*]] = icmp sge i64 [[INC]], 0 +; CHECK-NEXT: br i1 [[OK]], label [[LOOP_PREHEADER:%.*]], label [[FOR_END:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[INC]] +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END_LOOPEXIT:%.*]], label [[LOOP]] +; CHECK: for.end.loopexit: +; CHECK-NEXT: br label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: %inc = load i64, i64* %inc_ptr, !range !1 %ok = icmp sge i64 %inc, 0 @@ -263,7 +422,6 @@ entry: loop: %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] %indvars.iv.next = add nsw i64 %indvars.iv, %inc -; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %loop @@ -274,8 +432,21 @@ for.end: ; preds = %if.end, %entry ; check to handle loops without preheaders, but invariant operands ; (we handle this today by inserting a preheader) define void @test9(i1 %cnd, i64 %start) { -; CHECK-LABEL: @test9 -; CHECK-LABEL: loop.preheader: +; CHECK-LABEL: @test9( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[CND:%.*]], label [[ENTRY1:%.*]], label [[ENTRY2:%.*]] +; CHECK: entry1: +; CHECK-NEXT: br label [[LOOP_PREHEADER:%.*]] +; CHECK: entry2: +; CHECK-NEXT: br label [[LOOP_PREHEADER]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START:%.*]], -1 +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[LOOP]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: br i1 %cnd, label %entry1, label %entry2 entry1: @@ -285,7 +456,6 @@ entry2: loop: %indvars.iv = phi i64 [ %start, %entry1 ],[ %start, %entry2 ], [ %indvars.iv.next, %loop ] %indvars.iv.next = add nsw i64 %indvars.iv, 1 -; CHECK: %cmp1 = icmp slt i64 %start, -1 %cmp1 = icmp slt i64 %indvars.iv, -1 br i1 %cmp1, label %for.end, label %loop @@ -300,7 +470,26 @@ declare void @use(i1 %x) ; we have a "loop" which is known to run exactly one iteration but ; haven't yet simplified the uses of the IV define void @test10() { -; CHECK-LABEL: @test10 +; CHECK-LABEL: @test10( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI1:%.*]] = phi i32 [ [[PHI2:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[DEC:%.*]] = add nuw nsw i32 [[PHI1]], -1 +; CHECK-NEXT: br i1 false, label [[LEFT:%.*]], label [[RIGHT:%.*]] +; CHECK: left: +; CHECK-NEXT: br label [[LATCH]] +; CHECK: right: +; CHECK-NEXT: br label [[LATCH]] +; CHECK: latch: +; CHECK-NEXT: [[PHI2]] = phi i32 [ [[PHI1]], [[LEFT]] ], [ [[DEC]], [[RIGHT]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 -1, undef +; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]] +; CHECK: exit: +; CHECK-NEXT: [[CMP_LCSSA:%.*]] = phi i1 [ [[CMP]], [[LATCH]] ] +; CHECK-NEXT: call void @use(i1 [[CMP_LCSSA]]) +; CHECK-NEXT: ret void +; entry: br label %loop @@ -317,7 +506,6 @@ right: latch: %phi2 = phi i32 [ %phi1, %left ], [ %dec, %right ] - ; CHECK: %cmp = icmp slt i32 -1, undef %cmp = icmp slt i32 %phi2, undef br i1 true, label %exit, label %loop @@ -329,7 +517,29 @@ exit: ; check that we can figure out that iv.next > 1 from the facts that iv >= 0 and ; iv.start != 0. define void @test11(i64* %inc_ptr) { -; CHECK-LABEL: @test11 +; CHECK-LABEL: @test11( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !0 +; CHECK-NEXT: [[NE_COND:%.*]] = icmp ne i64 [[INC]], 0 +; CHECK-NEXT: br i1 [[NE_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] +; CHECK: loop.preheader: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[INC]], [[LOOP_PREHEADER]] ] +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 +; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: if.false: +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], 201 +; 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: %inc = load i64, i64* %inc_ptr, !range !0 %ne.cond = icmp ne i64 %inc, 0 @@ -339,7 +549,6 @@ loop: %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ] %iv.next = add i64 %iv, 1 %brcond = icmp sgt i64 %iv.next, 1 - ; CHECK: br i1 true, label %if.true, label %if.false br i1 %brcond, label %if.true, label %if.false if.true: @@ -359,7 +568,24 @@ exit: ; check that we can prove that a recurrency is greater than another recurrency ; in the same loop, with the same step, and with smaller starting value. define void @test12(i64* %inc_ptr) { -; CHECK-LABEL: @test12 +; CHECK-LABEL: @test12( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[INC:%.*]] = load i64, i64* [[INC_PTR:%.*]], !range !0 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 +; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; CHECK: if.true: +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: if.false: +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], 201 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; entry: %inc = load i64, i64* %inc_ptr, !range !0 %inc.minus.1 = sub i64 %inc, 1 @@ -371,7 +597,6 @@ loop: %iv.next = add i64 %iv, 1 %iv.minus.1.next = add i64 %iv.minus.1, 1 %brcond = icmp sgt i64 %iv.next, %iv.minus.1.next - ; CHECK: br i1 true, label %if.true, label %if.false br i1 %brcond, label %if.true, label %if.false if.true: diff --git a/test/Transforms/IndVarSimplify/lrev-existing-umin.ll b/test/Transforms/IndVarSimplify/lrev-existing-umin.ll index fff76675f17..6ef7a5ce9e2 100644 --- a/test/Transforms/IndVarSimplify/lrev-existing-umin.ll +++ b/test/Transforms/IndVarSimplify/lrev-existing-umin.ll @@ -1,9 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -indvars < %s | FileCheck %s ; Do not rewrite the user outside the loop because we must keep the instruction ; inside the loop due to store. Rewrite doesn't give us any profit. define void @f(i32 %length.i.88, i32 %length.i, i8* %tmp12, i32 %tmp10, i8* %tmp8) { ; CHECK-LABEL: @f( +; CHECK-NEXT: not_zero11.preheader: +; CHECK-NEXT: [[TMP13:%.*]] = icmp ugt i32 [[LENGTH_I:%.*]], [[LENGTH_I_88:%.*]] +; CHECK-NEXT: [[TMP14:%.*]] = select i1 [[TMP13]], i32 [[LENGTH_I_88]], i32 [[LENGTH_I]] +; CHECK-NEXT: [[TMP15:%.*]] = icmp sgt i32 [[TMP14]], 0 +; CHECK-NEXT: br i1 [[TMP15]], label [[NOT_ZERO11_PREHEADER1:%.*]], label [[NOT_ZERO11_POSTLOOP:%.*]] +; CHECK: not_zero11.preheader1: +; CHECK-NEXT: br label [[NOT_ZERO11:%.*]] +; CHECK: not_zero11: +; CHECK-NEXT: [[V_1:%.*]] = phi i32 [ [[TMP22:%.*]], [[NOT_ZERO11]] ], [ 0, [[NOT_ZERO11_PREHEADER1]] ] +; CHECK-NEXT: [[TMP16:%.*]] = zext i32 [[V_1]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i8, i8* [[TMP8:%.*]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = load i8, i8* [[TMP17]], align 1 +; CHECK-NEXT: [[TMP19:%.*]] = zext i8 [[TMP18]] to i32 +; CHECK-NEXT: [[TMP20:%.*]] = or i32 [[TMP19]], [[TMP10:%.*]] +; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i8 +; CHECK-NEXT: [[ADDR22:%.*]] = getelementptr inbounds i8, i8* [[TMP12:%.*]], i64 [[TMP16]] +; CHECK-NEXT: store i8 [[TMP21]], i8* [[ADDR22]], align 1 +; CHECK-NEXT: [[TMP22]] = add nuw nsw i32 [[V_1]], 1 +; CHECK-NEXT: [[TMP23:%.*]] = icmp slt i32 [[TMP22]], [[TMP14]] +; CHECK-NEXT: br i1 [[TMP23]], label [[NOT_ZERO11]], label [[MAIN_EXIT_SELECTOR:%.*]] +; CHECK: main.exit.selector: +; CHECK-NEXT: [[TMP22_LCSSA:%.*]] = phi i32 [ [[TMP22]], [[NOT_ZERO11]] ] +; CHECK-NEXT: [[TMP24:%.*]] = icmp slt i32 [[TMP22_LCSSA]], [[LENGTH_I]] +; CHECK-NEXT: br i1 [[TMP24]], label [[NOT_ZERO11_POSTLOOP]], label [[LEAVE:%.*]] +; CHECK: leave: +; CHECK-NEXT: ret void +; CHECK: not_zero11.postloop: +; CHECK-NEXT: ret void +; not_zero11.preheader: %tmp13 = icmp ugt i32 %length.i, %length.i.88 %tmp14 = select i1 %tmp13, i32 %length.i.88, i32 %length.i @@ -25,9 +55,6 @@ not_zero11: br i1 %tmp23, label %not_zero11, label %main.exit.selector main.exit.selector: -; CHECK-LABEL: main.exit.selector: -; CHECK: %tmp22.lcssa = phi i32 [ %tmp22, %not_zero11 ] -; CHECK: %tmp24 = icmp slt i32 %tmp22.lcssa, %length. %tmp24 = icmp slt i32 %tmp22, %length.i br i1 %tmp24, label %not_zero11.postloop, label %leave @@ -41,6 +68,32 @@ not_zero11.postloop: ; Rewrite the user outside the loop because there is no hard users inside the loop. define void @f1(i32 %length.i.88, i32 %length.i, i8* %tmp12, i32 %tmp10, i8* %tmp8) { ; CHECK-LABEL: @f1( +; CHECK-NEXT: not_zero11.preheader: +; CHECK-NEXT: [[TMP13:%.*]] = icmp ugt i32 [[LENGTH_I:%.*]], [[LENGTH_I_88:%.*]] +; CHECK-NEXT: [[TMP14:%.*]] = select i1 [[TMP13]], i32 [[LENGTH_I_88]], i32 [[LENGTH_I]] +; CHECK-NEXT: [[TMP15:%.*]] = icmp sgt i32 [[TMP14]], 0 +; CHECK-NEXT: br i1 [[TMP15]], label [[NOT_ZERO11_PREHEADER1:%.*]], label [[NOT_ZERO11_POSTLOOP:%.*]] +; CHECK: not_zero11.preheader1: +; CHECK-NEXT: br label [[NOT_ZERO11:%.*]] +; CHECK: not_zero11: +; CHECK-NEXT: [[V_1:%.*]] = phi i32 [ [[TMP22:%.*]], [[NOT_ZERO11]] ], [ 0, [[NOT_ZERO11_PREHEADER1]] ] +; CHECK-NEXT: [[TMP16:%.*]] = zext i32 [[V_1]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i8, i8* [[TMP8:%.*]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = load i8, i8* [[TMP17]], align 1 +; CHECK-NEXT: [[TMP19:%.*]] = zext i8 [[TMP18]] to i32 +; CHECK-NEXT: [[TMP20:%.*]] = or i32 [[TMP19]], [[TMP10:%.*]] +; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i8 +; CHECK-NEXT: [[ADDR22:%.*]] = getelementptr inbounds i8, i8* [[TMP12:%.*]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP22]] = add nuw nsw i32 [[V_1]], 1 +; CHECK-NEXT: br i1 false, label [[NOT_ZERO11]], label [[MAIN_EXIT_SELECTOR:%.*]] +; CHECK: main.exit.selector: +; CHECK-NEXT: [[TMP24:%.*]] = icmp slt i32 [[TMP14]], [[LENGTH_I]] +; CHECK-NEXT: br i1 [[TMP24]], label [[NOT_ZERO11_POSTLOOP]], label [[LEAVE:%.*]] +; CHECK: leave: +; CHECK-NEXT: ret void +; CHECK: not_zero11.postloop: +; CHECK-NEXT: ret void +; not_zero11.preheader: %tmp13 = icmp ugt i32 %length.i, %length.i.88 %tmp14 = select i1 %tmp13, i32 %length.i.88, i32 %length.i @@ -61,8 +114,6 @@ not_zero11: br i1 %tmp23, label %not_zero11, label %main.exit.selector main.exit.selector: -; CHECK-LABEL: main.exit.selector: -; CHECK: %tmp24 = icmp slt i32 %tmp14, %length.i %tmp24 = icmp slt i32 %tmp22, %length.i br i1 %tmp24, label %not_zero11.postloop, label %leave diff --git a/test/Transforms/IndVarSimplify/pr28705.ll b/test/Transforms/IndVarSimplify/pr28705.ll new file mode 100644 index 00000000000..a6fed805dc6 --- /dev/null +++ b/test/Transforms/IndVarSimplify/pr28705.ll @@ -0,0 +1,65 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; PR28705 +; RUN: opt < %s -indvars -S | FileCheck %s + +; Check IndVarSimplify doesn't replace external use of the induction var +; "%inc.i.i" with "%.sroa.speculated + 1" because it is not profitable. +; +; +define void @foo(i32 %sub.ptr.div.i, i8* %ref.i1174) local_unnamed_addr { +; CHECK-LABEL: @foo( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP_I1137:%.*]] = icmp ugt i32 [[SUB_PTR_DIV_I:%.*]], 3 +; CHECK-NEXT: [[DOTSROA_SPECULATED:%.*]] = select i1 [[CMP_I1137]], i32 3, i32 [[SUB_PTR_DIV_I]] +; CHECK-NEXT: [[CMP6483126:%.*]] = icmp eq i32 [[DOTSROA_SPECULATED]], 0 +; CHECK-NEXT: br i1 [[CMP6483126]], label [[XZ_EXIT:%.*]], label [[FOR_BODY650_LR_PH:%.*]] +; CHECK: for.body650.lr.ph: +; CHECK-NEXT: br label [[FOR_BODY650:%.*]] +; CHECK: loopexit: +; CHECK-NEXT: [[INC_I_I_LCSSA:%.*]] = phi i32 [ [[INC_I_I:%.*]], [[FOR_BODY650]] ] +; CHECK-NEXT: br label [[XZ_EXIT]] +; CHECK: XZ.exit: +; CHECK-NEXT: [[DB_SROA_9_0_LCSSA:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[INC_I_I_LCSSA]], [[LOOPEXIT:%.*]] ] +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: for.body650: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[FOR_BODY650_LR_PH]] ], [ [[INC655:%.*]], [[FOR_BODY650]] ] +; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 1, [[FOR_BODY650_LR_PH]] ], [ [[INC_I_I]], [[FOR_BODY650]] ] +; CHECK-NEXT: [[ARRAYIDX_I_I1105:%.*]] = getelementptr inbounds i8, i8* [[REF_I1174:%.*]], i32 [[IV2]] +; CHECK-NEXT: store i8 7, i8* [[ARRAYIDX_I_I1105]], align 1 +; CHECK-NEXT: [[INC_I_I]] = add nuw nsw i32 [[IV2]], 1 +; CHECK-NEXT: [[INC655]] = add nuw nsw i32 [[IV]], 1 +; CHECK-NEXT: [[CMP648:%.*]] = icmp eq i32 [[INC655]], [[DOTSROA_SPECULATED]] +; CHECK-NEXT: br i1 [[CMP648]], label [[LOOPEXIT]], label [[FOR_BODY650]] +; CHECK: end: +; CHECK-NEXT: ret void +; +entry: + %cmp.i1137 = icmp ugt i32 %sub.ptr.div.i, 3 + %.sroa.speculated = select i1 %cmp.i1137, i32 3, i32 %sub.ptr.div.i + %cmp6483126 = icmp eq i32 %.sroa.speculated, 0 + br i1 %cmp6483126, label %XZ.exit, label %for.body650.lr.ph + +for.body650.lr.ph: + br label %for.body650 + +loopexit: + %inc.i.i.lcssa = phi i32 [ %inc.i.i, %for.body650 ] + br label %XZ.exit + +XZ.exit: + %DB.sroa.9.0.lcssa = phi i32 [ 1, %entry ], [ %inc.i.i.lcssa, %loopexit ] + br label %end + +for.body650: + %iv = phi i32 [ 0, %for.body650.lr.ph ], [ %inc655, %for.body650 ] + %iv2 = phi i32 [ 1, %for.body650.lr.ph ], [ %inc.i.i, %for.body650 ] + %arrayidx.i.i1105 = getelementptr inbounds i8, i8* %ref.i1174, i32 %iv2 + store i8 7, i8* %arrayidx.i.i1105, align 1 + %inc.i.i = add i32 %iv2, 1 + %inc655 = add i32 %iv, 1 + %cmp648 = icmp eq i32 %inc655, %.sroa.speculated + br i1 %cmp648, label %loopexit, label %for.body650 + +end: + ret void +} diff --git a/test/Transforms/IndVarSimplify/widen-loop-comp.ll b/test/Transforms/IndVarSimplify/widen-loop-comp.ll index 5630c5dd075..bc06d3ff743 100644 --- a/test/Transforms/IndVarSimplify/widen-loop-comp.ll +++ b/test/Transforms/IndVarSimplify/widen-loop-comp.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -indvars -S | FileCheck %s target triple = "aarch64--linux-gnu" @@ -12,15 +13,42 @@ target datalayout = "n8:16:32:64" @e = common global i32 0, align 4 @ptr = common global i32* null, align 8 -; CHECK-LABEL: @test1 -; CHECK: for.body.lr.ph: -; CHECK: sext i32 -; CHECK: for.cond: -; CHECK: icmp slt i64 -; CHECK: for.body: -; CHECK: phi i64 define i32 @test1() { +; CHECK-LABEL: @test1( +; CHECK-NEXT: entry: +; CHECK-NEXT: store i32 -1, i32* @idx, align 4 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @e, align 4 +; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i32 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[CMP4]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY_LR_PH:%.*]] +; CHECK: for.body.lr.ph: +; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** @ptr, align 8 +; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* @e, align 4 +; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[TMP2]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV:%.*]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP3]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_LOOPEXIT_CRIT_EDGE:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV]] = phi i64 [ [[INDVARS_IV_NEXT]], [[FOR_COND:%.*]] ], [ 0, [[FOR_BODY_LR_PH]] ] +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_COND]] +; CHECK: if.then: +; CHECK-NEXT: [[I_05_LCSSA_WIDE:%.*]] = phi i64 [ [[INDVARS_IV]], [[FOR_BODY]] ] +; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[I_05_LCSSA_WIDE]] to i32 +; CHECK-NEXT: store i32 [[TMP5]], i32* @idx, align 4 +; CHECK-NEXT: br label [[FOR_END:%.*]] +; CHECK: for.cond.for.end.loopexit_crit_edge: +; CHECK-NEXT: br label [[FOR_END_LOOPEXIT]] +; CHECK: for.end.loopexit: +; CHECK-NEXT: br label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* @idx, align 4 +; CHECK-NEXT: ret i32 [[TMP6]] +; entry: store i32 -1, i32* @idx, align 4 %0 = load i32, i32* @e, align 4 @@ -61,14 +89,50 @@ for.end: ret i32 %4 } -; CHECK-LABEL: @test2 -; CHECK: for.body4.us -; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 -; CHECK: %cmp2.us = icmp ult i64 -; CHECK-NOT: %2 = trunc i64 %indvars.iv.next to i32 -; CHECK-NOT: %cmp2.us = icmp slt i32 define void @test2([8 x i8]* %a, i8* %b, i8 %limit) { +; CHECK-LABEL: @test2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[LIMIT:%.*]] to i32 +; CHECK-NEXT: br i1 undef, label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]] +; CHECK: for.cond1.preheader.us.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[CONV]] to i64 +; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]] +; CHECK: for.cond1.preheader.preheader: +; CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]] +; CHECK: for.cond1.preheader.us: +; CHECK-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ], [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC13_US:%.*]] ] +; CHECK-NEXT: br i1 true, label [[FOR_BODY4_LR_PH_US:%.*]], label [[FOR_INC13_US]] +; CHECK: for.inc13.us.loopexit: +; CHECK-NEXT: br label [[FOR_INC13_US]] +; CHECK: for.inc13.us: +; CHECK-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT3]], 4 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END_LOOPEXIT1:%.*]] +; CHECK: for.body4.us: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[FOR_BODY4_LR_PH_US]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY4_US:%.*]] ] +; CHECK-NEXT: [[ARRAYIDX6_US:%.*]] = getelementptr inbounds [8 x i8], [8 x i8]* [[A:%.*]], i64 [[INDVARS_IV2]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[ARRAYIDX6_US]], align 1 +; CHECK-NEXT: [[IDXPROM7_US:%.*]] = zext i8 [[TMP1]] to i64 +; CHECK-NEXT: [[ARRAYIDX8_US:%.*]] = getelementptr inbounds i8, i8* [[B:%.*]], i64 [[IDXPROM7_US]] +; CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[ARRAYIDX8_US]], align 1 +; CHECK-NEXT: store i8 [[TMP2]], i8* [[ARRAYIDX6_US]], align 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_INC13_US_LOOPEXIT:%.*]] +; CHECK: for.body4.lr.ph.us: +; CHECK-NEXT: br label [[FOR_BODY4_US]] +; CHECK: for.cond1.preheader: +; CHECK-NEXT: br i1 false, label [[FOR_INC13:%.*]], label [[FOR_INC13]] +; CHECK: for.inc13: +; CHECK-NEXT: br i1 false, label [[FOR_COND1_PREHEADER]], label [[FOR_END_LOOPEXIT:%.*]] +; CHECK: for.end.loopexit: +; CHECK-NEXT: br label [[FOR_END:%.*]] +; CHECK: for.end.loopexit1: +; CHECK-NEXT: br label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: %conv = zext i8 %limit to i32 br i1 undef, label %for.cond1.preheader, label %for.cond1.preheader.us @@ -112,13 +176,27 @@ for.end: ret void } -; CHECK-LABEL: @test3 -; CHECK: sext i32 %b -; CHECK: for.cond: -; CHECK: phi i64 -; CHECK: icmp slt i64 define i32 @test3(i32* %a, i32 %b) { +; CHECK-LABEL: @test3( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[B:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: br label [[FOR_COND]] +; CHECK: for.end: +; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] +; entry: br label %for.cond @@ -143,12 +221,23 @@ for.end: declare i32 @fn1(i8 signext) ; PR21030 -; CHECK-LABEL: @test4 -; CHECK: for.body: -; CHECK: phi i32 -; CHECK: icmp sgt i8 define i32 @test4(i32 %a) { +; CHECK-LABEL: @test4( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 253, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[INDVARS_IV]] +; CHECK-NEXT: [[CONV3:%.*]] = trunc i32 [[OR]] to i8 +; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i8 signext [[CONV3]]) +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], -1 +; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[INDVARS_IV_NEXT]] to i8 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[TMP0]], -14 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: ret i32 0 +; entry: br label %for.body @@ -166,13 +255,27 @@ for.end: ret i32 0 } -; CHECK-LABEL: @test5 -; CHECK: zext i32 %b -; CHECK: for.cond: -; CHECK: phi i64 -; CHECK: icmp ule i64 define i32 @test5(i32* %a, i32 %b) { +; CHECK-LABEL: @test5( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: br label [[FOR_COND]] +; CHECK: for.end: +; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] +; entry: br label %for.cond @@ -196,10 +299,24 @@ for.end: define i32 @test6(i32* %a, i32 %b) { ; CHECK-LABEL: @test6( -; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64 -; CHECK: for.cond: -; CHECK: icmp sle i64 %indvars.iv, [[B_SEXT]] - +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[B:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[INDVARS_IV]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP1]] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: br label [[FOR_COND]] +; CHECK: for.end: +; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] +; entry: br label %for.cond @@ -223,13 +340,26 @@ for.end: define i32 @test7(i32* %a, i32 %b) { ; CHECK-LABEL: @test7( -; CHECK: [[B_ZEXT:%[a-z0-9]+]] = zext i32 %b to i64 -; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64 -; CHECK: for.cond: -; CHECK: icmp ule i64 %indvars.iv, [[B_ZEXT]] -; CHECK: for.body: -; CHECK: icmp sle i64 %indvars.iv, [[B_SEXT]] - +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[B:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[B]] to i64 +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP0]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i64 [[INDVARS_IV]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] +; entry: br label %for.cond @@ -253,14 +383,33 @@ for.end: } define i32 @test8(i32* %a, i32 %b, i32 %init) { -; CHECK-LABEL: @test8( -; CHECK: [[INIT_SEXT:%[a-z0-9]+]] = sext i32 %init to i64 -; CHECK: [[B_ZEXT:%[a-z0-9]+]] = zext i32 %b to i64 -; CHECK: for.cond: ; Note: %indvars.iv is the sign extension of %i.0 -; CHECK: %indvars.iv = phi i64 [ [[INIT_SEXT]], %for.cond.preheader ], [ %indvars.iv.next, %for.body ] -; CHECK: icmp ule i64 %indvars.iv, [[B_ZEXT]] - +; CHECK-LABEL: @test8( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0 +; CHECK-NEXT: br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]] +; CHECK: for.cond.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[INIT]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[B:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ] +; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 0, [[INDVARS_IV_NEXT]] +; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] +; CHECK: leave: +; CHECK-NEXT: ret i32 0 +; entry: %e = icmp sgt i32 %init, 0 br i1 %e, label %for.cond, label %leave @@ -288,14 +437,34 @@ leave: } define i32 @test9(i32* %a, i32 %b, i32 %init) { -; CHECK-LABEL: @test9( -; CHECK: [[INIT_ZEXT:%[a-z0-9]+]] = zext i32 %init to i64 -; CHECK: [[B_SEXT:%[a-z0-9]+]] = sext i32 %b to i64 -; CHECK: for.cond: ; Note: %indvars.iv is the zero extension of %i.0 -; CHECK: %indvars.iv = phi i64 [ [[INIT_ZEXT]], %for.cond.preheader ], [ %indvars.iv.next, %for.body ] -; CHECK: icmp slt i64 %indvars.iv, [[B_SEXT]] - +; CHECK-LABEL: @test9( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[E:%.*]] = icmp sgt i32 [[INIT:%.*]], 0 +; CHECK-NEXT: br i1 [[E]], label [[FOR_COND_PREHEADER:%.*]], label [[LEAVE:%.*]] +; CHECK: for.cond.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[INIT]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[B:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ] +; CHECK-NEXT: [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] +; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[ADD]] = add nsw i32 [[SUM_0]], [[TMP2]] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 0, [[TMP3]] +; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_COND]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0]], [[FOR_BODY]] ], [ [[SUM_0]], [[FOR_COND]] ] +; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]] +; CHECK: leave: +; CHECK-NEXT: ret i32 0 +; entry: %e = icmp sgt i32 %init, 0 br i1 %e, label %for.cond, label %leave @@ -327,18 +496,25 @@ declare void @consume.i1(i1) define i32 @test10(i32 %v) { ; CHECK-LABEL: @test10( - entry: -; CHECK-NOT: zext +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[V:%.*]] to i64 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = mul nsw i64 [[INDVARS_IV]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], [[SEXT]] +; CHECK-NEXT: call void @consume.i1(i1 [[TMP1]]) +; CHECK-NEXT: call void @consume.i64(i64 [[TMP0]]) +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 11 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE:%.*]] +; CHECK: leave: +; CHECK-NEXT: ret i32 22 +; + entry: br label %loop - loop: -; CHECK: [[WIDE_V:%[a-z0-9]+]] = sext i32 %v to i64 -; CHECK: loop: -; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ] -; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 -; CHECK: [[MUL:%[a-z0-9]+]] = mul nsw i64 %indvars.iv, -1 -; CHECK: [[CMP:%[a-z0-9]+]] = icmp eq i64 [[MUL]], [[WIDE_V]] -; CHECK: call void @consume.i1(i1 [[CMP]]) + loop: %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ] %i.inc = add i32 %i, 1 @@ -350,6 +526,6 @@ define i32 @test10(i32 %v) { call void @consume.i64(i64 %ext) br i1 %be.cond, label %loop, label %leave - leave: + leave: ret i32 22 }