1; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s 2; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -S < %s 2>&1 | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" 5target triple = "x86_64-unknown-linux-gnu" 6 7; IRCE should fail here because the preheader's exiting value is a phi from the 8; loop, and this value cannot be expanded at loop's preheader. 9 10; CHECK-NOT: irce: in function test_01: constrained Loop 11; CHECK-NOT: irce: in function test_02: constrained Loop 12; CHECK-LABEL: irce: in function test_03: constrained Loop 13 14define void @test_01() { 15 16; CHECK-NOT: irce: in function test_01: constrained Loop 17 18; CHECK-LABEL: test_01 19; CHECK-NOT: preloop 20; CHECK-NOT: postloop 21; CHECK-NOT: br i1 false 22; CHECK-NOT: br i1 true 23 24entry: 25 br label %loop 26 27exit: ; preds = %guarded, %loop 28 ret void 29 30loop: ; preds = %guarded, %entry 31 %iv = phi i64 [ 380, %entry ], [ %limit, %guarded ] 32 %bad_phi = phi i32 [ 3, %entry ], [ %bad_phi.next, %guarded ] 33 %bad_phi.next = add nuw nsw i32 %bad_phi, 1 34 %iv.next = add nuw nsw i64 %iv, 1 35 %rc = icmp slt i64 %iv.next, 5 36 br i1 %rc, label %guarded, label %exit 37 38guarded: 39 %limit = add nsw i64 %iv, -1 40 %tmp5 = add nuw nsw i32 %bad_phi, 8 41 %tmp6 = zext i32 %tmp5 to i64 42 %tmp7 = icmp eq i64 %limit, %tmp6 43 br i1 %tmp7, label %exit, label %loop 44} 45 46; This test should fail because we are unable to prove that the division is 47; safe to expand it to preheader: if we exit by maybe_exit condition, it is 48; unsafe to execute it there. 49 50define void @test_02(i64* %p1, i64* %p2, i1 %maybe_exit) { 51 52; CHECK-LABEL: test_02 53; CHECK-NOT: preloop 54; CHECK-NOT: postloop 55; CHECK-NOT: br i1 false 56; CHECK-NOT: br i1 true 57 58 59entry: 60 %num = load i64, i64* %p1, align 4, !range !0 61 %denom = load i64, i64* %p2, align 4, !range !0 62 br label %loop 63 64exit: ; preds = %guarded, %loop 65 ret void 66 67loop: ; preds = %guarded, %entry 68 %iv = phi i64 [ 0, %entry ], [ %iv.next, %guarded ] 69 %iv.next = add nuw nsw i64 %iv, 1 70 br i1 %maybe_exit, label %range_check, label %exit 71 72range_check: 73 %div_result = udiv i64 %num, %denom 74 %rc = icmp slt i64 %iv.next, %div_result 75 br i1 %rc, label %guarded, label %exit 76 77guarded: 78 %gep = getelementptr i64, i64* %p1, i64 %iv.next 79 %loaded = load i64, i64* %gep, align 4 80 %tmp7 = icmp slt i64 %iv.next, 1000 81 br i1 %tmp7, label %loop, label %exit 82} 83 84define void @test_03(i64* %p1, i64* %p2, i1 %maybe_exit) { 85 86; Show that IRCE would hit test_02 if the division was safe (denom not zero). 87 88; CHECK-LABEL: test_03 89; CHECK: entry: 90; CHECK-NEXT: %num = load i64, i64* %p1, align 4 91; CHECK-NEXT: [[DIV:%[^ ]+]] = udiv i64 %num, 13 92; CHECK-NEXT: [[DIV_MINUS_1:%[^ ]+]] = add nsw i64 [[DIV]], -1 93; CHECK-NEXT: [[COMP1:%[^ ]+]] = icmp sgt i64 [[DIV_MINUS_1]], 0 94; CHECK-NEXT: %exit.mainloop.at = select i1 [[COMP1]], i64 [[DIV_MINUS_1]], i64 0 95; CHECK-NEXT: [[COMP2:%[^ ]+]] = icmp slt i64 0, %exit.mainloop.at 96; CHECK-NEXT: br i1 [[COMP2]], label %loop.preheader, label %main.pseudo.exit 97; CHECK-NOT: preloop 98; CHECK: loop: 99; CHECK-NEXT: %iv = phi i64 [ %iv.next, %guarded ], [ 0, %loop.preheader ] 100; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1 101; CHECK-NEXT: %rc = icmp slt i64 %iv.next, %div_result 102; CHECK-NEXT: %or.cond = and i1 %maybe_exit, true 103; CHECK-NEXT: br i1 %or.cond, label %guarded, label %exit.loopexit1 104; CHECK: guarded: 105; CHECK-NEXT: %gep = getelementptr i64, i64* %p1, i64 %iv.next 106; CHECK-NEXT: %loaded = load i64, i64* %gep, align 4 107; CHECK-NEXT: %tmp7 = icmp slt i64 %iv.next, 1000 108; CHECK-NEXT: [[EXIT_MAIN_LOOP:%[^ ]+]] = icmp slt i64 %iv.next, %exit.mainloop.at 109; CHECK-NEXT: br i1 [[EXIT_MAIN_LOOP]], label %loop, label %main.exit.selector 110; CHECK: postloop 111 112entry: 113 %num = load i64, i64* %p1, align 4, !range !0 114 br label %loop 115 116exit: ; preds = %guarded, %loop 117 ret void 118 119loop: ; preds = %guarded, %entry 120 %iv = phi i64 [ 0, %entry ], [ %iv.next, %guarded ] 121 %iv.next = add nuw nsw i64 %iv, 1 122 br i1 %maybe_exit, label %range_check, label %exit 123 124range_check: 125 %div_result = udiv i64 %num, 13 126 %rc = icmp slt i64 %iv.next, %div_result 127 br i1 %rc, label %guarded, label %exit 128 129guarded: 130 %gep = getelementptr i64, i64* %p1, i64 %iv.next 131 %loaded = load i64, i64* %gep, align 4 132 %tmp7 = icmp slt i64 %iv.next, 1000 133 br i1 %tmp7, label %loop, label %exit 134} 135 136!0 = !{i64 0, i64 100} 137