From 19823a1fcfe7e982de705b94e89c3c3e014462be Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 20 May 2019 19:13:04 +0000 Subject: [PATCH] [LFTR] Add additional PR31181 test cases One case where overflow happens in the first loop iteration, and two cases where we switch to a dynamically dead IV with post/pre increment, respectively. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361189 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Transforms/IndVarSimplify/pr31181.ll | 122 ++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/test/Transforms/IndVarSimplify/pr31181.ll b/test/Transforms/IndVarSimplify/pr31181.ll index c5870be60a7..453bb841929 100644 --- a/test/Transforms/IndVarSimplify/pr31181.ll +++ b/test/Transforms/IndVarSimplify/pr31181.ll @@ -117,6 +117,33 @@ exit: ret i32 0 } +define i32 @test_no_add_nuw() { +; CHECK-LABEL: @test_no_add_nuw( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] +; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a +; CHECK-NEXT: [[INC]] = add nsw i32 [[STOREMERGE]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], 10 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret i32 0 +; +entry: + br label %loop + +loop: + %storemerge = phi i32 [ -1, %entry ], [ %inc, %loop ] + store i32 %storemerge, i32* @a + %cmp = icmp slt i32 %storemerge, 9 + %inc = add i32 %storemerge, 1 + br i1 %cmp, label %loop, label %exit + +exit: + ret i32 0 +} + define i32 @test_drop_nsw_var_lim(i32 %lim) { ; CHECK-LABEL: @test_drop_nsw_var_lim( ; CHECK-NEXT: entry: @@ -150,3 +177,98 @@ loop: exit: ret i32 0 } + +; Adopted from D30446. +; We switch from %iv to %iv2 and need to change nsw to nuw in the process. +define i32 @switch_to_different_iv_pos_inc(i32* %ptr, i1 %always_false) { +; CHECK-LABEL: @switch_to_different_iv_pos_inc( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[ALWAYS_TAKEN:%.*]] ] +; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV2_INC:%.*]], [[ALWAYS_TAKEN]] ] +; CHECK-NEXT: store i32 [[IV]], i32* [[PTR:%.*]] +; CHECK-NEXT: br i1 [[ALWAYS_FALSE:%.*]], label [[NEVER_TAKEN:%.*]], label [[ALWAYS_TAKEN]] +; CHECK: never_taken: +; CHECK-NEXT: store volatile i32 [[IV2]], i32* [[PTR]] +; CHECK-NEXT: br label [[ALWAYS_TAKEN]] +; CHECK: always_taken: +; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1 +; CHECK-NEXT: [[IV2_INC]] = add nuw nsw i32 [[IV2]], 1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483627 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: ret i32 0 +; +entry: + br label %for.cond + +for.cond: + %iv = phi i32 [ -2147483648, %entry ], [ %iv.inc, %always_taken ] + %iv2 = phi i32 [ 0, %entry ], [ %iv2.inc, %always_taken ] + store i32 %iv, i32* %ptr + br i1 %always_false, label %never_taken, label %always_taken + +never_taken: + store volatile i32 %iv2, i32* %ptr + br label %always_taken + +always_taken: + %iv.inc = add nsw i32 %iv, 1 + %iv2.inc = add nsw i32 %iv2, 1 + %cmp = icmp slt i32 %iv, 20 + br i1 %cmp, label %for.cond, label %for.end + +for.end: + ret i32 0 +} + +; Same as previous test case, but with exit block and loop latch being distinct +; blocks requiring the use of pre-increment. +define i32 @switch_to_different_iv_pre_inc(i32* %ptr, i1 %always_false) { +; CHECK-LABEL: @switch_to_different_iv_pre_inc( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[ALWAYS_TAKEN:%.*]] ] +; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV2_INC:%.*]], [[ALWAYS_TAKEN]] ] +; CHECK-NEXT: store i32 [[IV]], i32* [[PTR:%.*]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2]], -2147483628 +; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br i1 [[ALWAYS_FALSE:%.*]], label [[NEVER_TAKEN:%.*]], label [[ALWAYS_TAKEN]] +; CHECK: never_taken: +; CHECK-NEXT: store volatile i32 [[IV2]], i32* [[PTR]] +; CHECK-NEXT: br label [[ALWAYS_TAKEN]] +; CHECK: always_taken: +; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1 +; CHECK-NEXT: [[IV2_INC]] = add nuw nsw i32 [[IV2]], 1 +; CHECK-NEXT: br label [[FOR_COND]] +; CHECK: for.end: +; CHECK-NEXT: ret i32 0 +; +entry: + br label %for.cond + +for.cond: + %iv = phi i32 [ -2147483648, %entry ], [ %iv.inc, %always_taken ] + %iv2 = phi i32 [ 0, %entry ], [ %iv2.inc, %always_taken ] + store i32 %iv, i32* %ptr + %cmp = icmp slt i32 %iv, 20 + br i1 %cmp, label %for.body, label %for.end + +for.body: + br i1 %always_false, label %never_taken, label %always_taken + +never_taken: + store volatile i32 %iv2, i32* %ptr + br label %always_taken + +always_taken: + %iv.inc = add nsw i32 %iv, 1 + %iv2.inc = add nsw i32 %iv2, 1 + br label %for.cond + +for.end: + ret i32 0 +} -- 2.40.0