Index: llvm/test/Transforms/IRCE/constrain_loop_with_phi_bound.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/IRCE/constrain_loop_with_phi_bound.ll @@ -0,0 +1,59 @@ +; RUN: opt -passes=irce -S -debug-only=irce < %s 2>&1 | FileCheck %s + +declare i32 @bar() + +; TODO: Prove that loop L1 is guarded by cond '0 =s 0', '%x02 >=s 0', '%x != 0', hence 'x >s 0' +define void @test_constrain_loop_with_phi_bound(i32 %n) { +; CHECK: irce: looking at loop Loop at depth 2 containing: %L1.header
,%L1.latch +; CHECK: irce: loop has 1 inductive range checks: +; CHECK: InductiveRangeCheck: +; CHECK: Begin: 0 Step: 1 End: %n +; CHECK: CheckUse: br i1 %cmp2, label %L1.latch, label %L1.exit Operand: 0 +; CHECK: irce: isSafeIncreasingBound with: +; CHECK: irce: Start: 0 +; CHECK: irce: Step: 1 +; CHECK: irce: BoundSCEV: %x +; CHECK: irce: Pred: slt +; CHECK: irce: LatchExitBrIdx: 1 +; CHECK: irce: could not parse loop structure: Unsafe loop bounds +Entry: + %x01 = call i32 @bar() + %cmp0 = icmp slt i32 %x01, 0 + br i1 %cmp0, label %Exit, label %L0.preheader + +L0.preheader: + br label %L0.header + +L0.header: + %x = phi i32 [ %x01, %L0.preheader ], [ %x02, %L0.latch ] + %cmp1 = icmp eq i32 %x, 0 + br i1 %cmp1, label %L0.exit, label %L1.preheader + +L1.preheader: + br label %L1.header + +L1.header: + %iv = phi i32 [ 0, %L1.preheader ], [ %iv.next, %L1.latch ] + %cmp2 = icmp ult i32 %iv, %n + br i1 %cmp2, label %L1.latch, label %L1.exit + +L1.latch: + %iv.next = add nuw nsw i32 %iv, 1 + %cmp3 = icmp slt i32 %iv.next, %x + br i1 %cmp3, label %L1.header, label %L0.latch + +L1.exit: + br label %Exit + +L0.latch: + %x02 = call i32 @bar() + %cmp4 = icmp slt i32 %x02, 0 + br i1 %cmp4, label %L0.exit, label %L0.header + +L0.exit: + br label %Exit + +Exit: + ret void +}