Skip to content

Commit

Permalink
[Test] Add tests showing congruent IVs not removed by IndVars
Browse files Browse the repository at this point in the history
In the added cases we have two congruent IVs. IndVars widens at least one of them.
If they are both widened, then one of them is erased as they stay congruent after
widening. However if only one IV is widened, the other one stays in the loop.
We can simply erase the narrow IV and replace its uses with truncates of the
widest IV.
  • Loading branch information
d-makogon committed Nov 2, 2021
1 parent 1fc80ff commit 94128f0
Showing 1 changed file with 138 additions and 0 deletions.
138 changes: 138 additions & 0 deletions llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll
Expand Up @@ -1302,3 +1302,141 @@ exit:
failure:
unreachable
}

declare void @foo(i64 %v)
declare void @bar(i32 %v)

define void @test18() {
; CHECK-LABEL: @test18(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: call void @bar(i32 [[IV_NEXT]])
; CHECK-NEXT: call void @foo(i64 [[INDVARS_IV]])
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop

loop: ; preds = %loop, %entry
%iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
%val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
%val1.inc = add i32 %val1, 1
%iv.next = add i32 %iv, 1
call void @bar(i32 %val1.inc)
%iv.wide = zext i32 %iv to i64
call void @foo(i64 %iv.wide)
%loop.cond = icmp eq i32 %iv, 1000
br i1 %loop.cond, label %exit, label %loop

exit: ; preds = %loop
ret void
}

define void @test19() {
; CHECK-LABEL: @test19(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[VAL1:%.*]] = phi i64 [ [[VAL1_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[VAL1_INC]] = add nuw nsw i64 [[VAL1]], 1
; CHECK-NEXT: call void @foo(i64 [[VAL1_INC]])
; CHECK-NEXT: call void @foo(i64 [[VAL1]])
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i64 [[VAL1]], 1000
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop

loop: ; preds = %loop, %entry
%iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
%val1 = phi i64 [ %val1.inc, %loop ], [ 0, %entry ]
%val1.inc = add i64 %val1, 1
%iv.next = add i32 %iv, 1
call void @foo(i64 %val1.inc)
%iv.wide = zext i32 %iv to i64
call void @foo(i64 %iv.wide)
%loop.cond = icmp eq i32 %iv, 1000
br i1 %loop.cond, label %exit, label %loop

exit: ; preds = %loop
ret void
}

define void @test20() {
; CHECK-LABEL: @test20(
; CHECK-NEXT: entry:
; 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: call void @foo(i64 [[INDVARS_IV]])
; CHECK-NEXT: call void @foo(i64 [[INDVARS_IV]])
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop

loop: ; preds = %loop, %entry
%iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
%val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
%val1.inc = add i32 %val1, 1
%iv.next = add i32 %iv, 1
%val1.wide = zext i32 %val1 to i64
call void @foo(i64 %val1.wide)
%iv.wide = zext i32 %iv to i64
call void @foo(i64 %iv.wide)
%loop.cond = icmp eq i32 %iv, 1000
br i1 %loop.cond, label %exit, label %loop

exit: ; preds = %loop
ret void
}

define void @test21(i32* %ptr) {
; CHECK-LABEL: @test21(
; CHECK-NEXT: entry:
; CHECK-NEXT: store i32 0, i32* [[PTR:%.*]], align 4
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ [[VAL_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
; CHECK-NEXT: [[VAL_INC]] = add nuw nsw i32 [[VAL]], 1
; CHECK-NEXT: store i32 [[VAL_INC]], i32* [[PTR]], align 4
; CHECK-NEXT: call void @foo(i64 [[INDVARS_IV]])
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
store i32 0, i32* %ptr, align 4
br label %loop

loop: ; preds = %loop, %entry
%val = phi i32 [ %val.inc, %loop ], [ 0, %entry ]
%iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
%val.inc = add i32 %val, 1
store i32 %val.inc, i32* %ptr, align 4
%iv.wide = zext i32 %iv to i64
call void @foo(i64 %iv.wide)
%iv.next = add i32 %iv, 1
%loop.cond = icmp eq i32 %iv, 1000
br i1 %loop.cond, label %exit, label %loop

exit: ; preds = %loop
ret void
}

0 comments on commit 94128f0

Please sign in to comment.