The code already guards against values coming from a previous iteration using properlyDominates(). However, addrecs are considered to properly dominate the loop they are defined in. Handle this special case separately, by checking for expressions that have computable loop evolution (this should cover cases like a zext of an addrec as well). I considered changing the definition of properlyDominates() instead, but decided against it. The current definition is useful in other context, e.g. when deciding whether an expression is safe to expand in a given block. Fixes https://github.com/llvm/llvm-project/issues/126012.
54 lines
2.1 KiB
LLVM
54 lines
2.1 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt -S -passes=indvars < %s | FileCheck %s
|
|
|
|
; Do not infer that %cmp is true. The %indvar3 input of %indvar2 comes from
|
|
; a previous iteration, so we should not compare it to a value from the current
|
|
; iteration.
|
|
define i32 @test() {
|
|
; CHECK-LABEL: define i32 @test() {
|
|
; CHECK-NEXT: [[ENTRY:.*]]:
|
|
; CHECK-NEXT: br label %[[FOR_PREHEADER:.*]]
|
|
; CHECK: [[FOR_PREHEADER]]:
|
|
; CHECK-NEXT: [[INDVAR1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[PHI:%.*]], %[[FOR_INC:.*]] ]
|
|
; CHECK-NEXT: [[INDVAR2:%.*]] = phi i32 [ 1, %[[ENTRY]] ], [ [[INDVAR3:%.*]], %[[FOR_INC]] ]
|
|
; CHECK-NEXT: [[INDVAR3]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC:%.*]], %[[FOR_INC]] ]
|
|
; CHECK-NEXT: [[COND1:%.*]] = icmp eq i32 [[INDVAR3]], 0
|
|
; CHECK-NEXT: br i1 [[COND1]], label %[[FOR_INC]], label %[[FOR_END:.*]]
|
|
; CHECK: [[FOR_END]]:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[INDVAR2]], 0
|
|
; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[CMP]] to i32
|
|
; CHECK-NEXT: br label %[[FOR_INC]]
|
|
; CHECK: [[FOR_INC]]:
|
|
; CHECK-NEXT: [[PHI]] = phi i32 [ [[EXT]], %[[FOR_END]] ], [ 0, %[[FOR_PREHEADER]] ]
|
|
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[INDVAR3]], 1
|
|
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INDVAR3]], 2
|
|
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_EXIT:.*]], label %[[FOR_PREHEADER]]
|
|
; CHECK: [[FOR_EXIT]]:
|
|
; CHECK-NEXT: [[INDVAR1_LCSSA:%.*]] = phi i32 [ [[INDVAR1]], %[[FOR_INC]] ]
|
|
; CHECK-NEXT: ret i32 [[INDVAR1_LCSSA]]
|
|
;
|
|
entry:
|
|
br label %for.preheader
|
|
|
|
for.preheader:
|
|
%indvar1 = phi i32 [ 0, %entry ], [ %phi, %for.inc ]
|
|
%indvar2 = phi i32 [ 1, %entry ], [ %indvar3, %for.inc ]
|
|
%indvar3 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%cond1 = icmp eq i32 %indvar3, 0
|
|
br i1 %cond1, label %for.inc, label %for.end
|
|
|
|
for.end:
|
|
%cmp = icmp sgt i32 %indvar2, 0
|
|
%ext = zext i1 %cmp to i32
|
|
br label %for.inc
|
|
|
|
for.inc:
|
|
%phi = phi i32 [ %ext, %for.end ], [ 0, %for.preheader ]
|
|
%inc = add i32 %indvar3, 1
|
|
%exitcond = icmp eq i32 %indvar3, 2
|
|
br i1 %exitcond, label %for.exit, label %for.preheader
|
|
|
|
for.exit:
|
|
ret i32 %indvar1
|
|
}
|