diff --git a/llvm/test/Transforms/IndVarSimplify/post-inc-range.ll b/llvm/test/Transforms/IndVarSimplify/post-inc-range.ll index d859eb28e78d..3402d69078ad 100644 --- a/llvm/test/Transforms/IndVarSimplify/post-inc-range.ll +++ b/llvm/test/Transforms/IndVarSimplify/post-inc-range.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -indvars -indvars-post-increment-ranges -S | FileCheck %s target datalayout = "p:64:64:64-n32:64" @@ -8,7 +9,28 @@ target datalayout = "p:64:64:64-n32:64" ; is not-negative from the range check inside of the loop. define void @test(i32* %base, i32 %limit, i32 %start) { ; CHECK-LABEL: @test( -; CHECK-NOT: trunc +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[START:%.*]], i32 64) +; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[UMAX]], [[START]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[START]], 1 +; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[LIMIT:%.*]], i32 [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SMAX]], -1 +; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[TMP2]], [[START]] +; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP3]], i32 [[TMP0]]) +; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP0]], [[UMIN]] +; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP3]], [[UMIN]] +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br i1 [[TMP4]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] +; CHECK: continue: +; CHECK-NEXT: br label [[FOR_INC:%.*]] +; CHECK: for.inc: +; CHECK-NEXT: br i1 [[TMP5]], label [[FOR_BODY]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; for.body.lr.ph: br label %for.body @@ -38,7 +60,28 @@ exit: define void @test_false_edge(i32* %base, i32 %limit, i32 %start) { ; CHECK-LABEL: @test_false_edge( -; CHECK-NOT: trunc +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[START:%.*]], i32 65) +; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[UMAX]], [[START]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[START]], 1 +; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[LIMIT:%.*]], i32 [[TMP1]]) +; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SMAX]], -1 +; CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[TMP2]], [[START]] +; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP3]], i32 [[TMP0]]) +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], [[UMIN]] +; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP3]], [[UMIN]] +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br i1 [[TMP4]], label [[FOR_END:%.*]], label [[CONTINUE:%.*]] +; CHECK: continue: +; CHECK-NEXT: br label [[FOR_INC:%.*]] +; CHECK: for.inc: +; CHECK-NEXT: br i1 [[TMP5]], label [[FOR_BODY]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; for.body.lr.ph: br label %for.body @@ -67,9 +110,29 @@ exit: } define void @test_range_metadata(i32* %array_length_ptr, i32* %base, - i32 %limit, i32 %start) { ; CHECK-LABEL: @test_range_metadata( -; CHECK-NOT: trunc +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] +; CHECK-NEXT: [[ARRAY_LENGTH:%.*]] = load i32, i32* [[ARRAY_LENGTH_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]] +; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[ARRAY_LENGTH]] to i64 +; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], [[TMP2]] +; CHECK-NEXT: br i1 [[WITHIN_LIMITS]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] +; CHECK: continue: +; CHECK-NEXT: br label [[FOR_INC]] +; CHECK: for.inc: +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; + i32 %limit, i32 %start) { for.body.lr.ph: br label %for.body @@ -101,9 +164,29 @@ exit: ; Negative version of the test above, we don't know anything about ; array_length_ptr range. define void @test_neg(i32* %array_length_ptr, i32* %base, - i32 %limit, i32 %start) { ; CHECK-LABEL: @test_neg( -; CHECK: trunc i64 +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] +; CHECK-NEXT: [[ARRAY_LENGTH:%.*]] = load i32, i32* [[ARRAY_LENGTH_PTR:%.*]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[ARRAY_LENGTH]] to i64 +; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], [[TMP1]] +; CHECK-NEXT: br i1 [[WITHIN_LIMITS]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] +; CHECK: continue: +; CHECK-NEXT: br label [[FOR_INC]] +; CHECK: for.inc: +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP2]], [[LIMIT:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; + i32 %limit, i32 %start) { for.body.lr.ph: br label %for.body @@ -134,8 +217,36 @@ exit: define void @test_transitive_use(i32* %base, i32 %limit, i32 %start) { ; CHECK-LABEL: @test_transitive_use( -; CHECK-NOT: trunc -; CHECK: %result = icmp slt i64 +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 +; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[LIMIT]] to i64 +; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[START]], i32 64) +; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[UMAX]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[WIDE_TRIP_COUNT]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[CONTINUE:%.*]], label [[FOR_END:%.*]] +; CHECK: continue: +; CHECK-NEXT: [[TMP3:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 3 +; CHECK-NEXT: [[MUL_WITHIN:%.*]] = icmp ult i64 [[TMP3]], 64 +; CHECK-NEXT: br i1 [[MUL_WITHIN]], label [[GUARDED:%.*]], label [[CONTINUE_2:%.*]] +; CHECK: guarded: +; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[TMP3]], 1 +; CHECK-NEXT: [[RESULT:%.*]] = icmp slt i64 [[TMP4]], [[TMP1]] +; CHECK-NEXT: br i1 [[RESULT]], label [[CONTINUE_2]], label [[FOR_END]] +; CHECK: continue.2: +; CHECK-NEXT: br label [[FOR_INC]] +; CHECK: for.inc: +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP2]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; for.body.lr.ph: br label %for.body @@ -149,7 +260,7 @@ continue: %i.mul.3 = mul nsw nuw i32 %i, 3 %mul_within = icmp ult i32 %i.mul.3, 64 br i1 %mul_within, label %guarded, label %continue.2 - + guarded: %i.mul.3.inc = add nsw nuw i32 %i.mul.3, 1 %result = icmp slt i32 %i.mul.3.inc, %limit @@ -178,8 +289,22 @@ declare void @llvm.experimental.guard(i1, ...) define void @test_guard_one_bb(i32* %base, i32 %limit, i32 %start) { ; CHECK-LABEL: @test_guard_one_bb( -; CHECK-NOT: trunc -; CHECK-NOT: icmp slt i32 +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] +; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS]]) [ "deopt"() ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; for.body.lr.ph: br label %for.body @@ -204,8 +329,24 @@ exit: define void @test_guard_in_the_same_bb(i32* %base, i32 %limit, i32 %start) { ; CHECK-LABEL: @test_guard_in_the_same_bb( -; CHECK-NOT: trunc -; CHECK-NOT: icmp slt i32 +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] +; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 +; CHECK-NEXT: br label [[FOR_INC]] +; CHECK: for.inc: +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS]]) [ "deopt"() ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; for.body.lr.ph: br label %for.body @@ -233,8 +374,24 @@ exit: define void @test_guard_in_idom(i32* %base, i32 %limit, i32 %start) { ; CHECK-LABEL: @test_guard_in_idom( -; CHECK-NOT: trunc -; CHECK-NOT: icmp slt i32 +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] +; CHECK-NEXT: [[WITHIN_LIMITS:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS]]) [ "deopt"() ] +; CHECK-NEXT: br label [[FOR_INC]] +; CHECK: for.inc: +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; for.body.lr.ph: br label %for.body @@ -262,8 +419,24 @@ exit: define void @test_guard_merge_ranges(i32* %base, i32 %limit, i32 %start) { ; CHECK-LABEL: @test_guard_merge_ranges( -; CHECK-NOT: trunc -; CHECK-NOT: icmp slt i32 +; CHECK-NEXT: for.body.lr.ph: +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[LIMIT:%.*]] to i64 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[TMP0]], [[FOR_BODY_LR_PH:%.*]] ] +; CHECK-NEXT: [[WITHIN_LIMITS_1:%.*]] = icmp ult i64 [[INDVARS_IV]], 64 +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS_1]]) [ "deopt"() ] +; CHECK-NEXT: [[WITHIN_LIMITS_2:%.*]] = icmp ult i64 [[INDVARS_IV]], 2147483647 +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_LIMITS_2]]) [ "deopt"() ] +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; for.body.lr.ph: br label %for.body