289 lines · plain
1; RUN: opt -verify-loop-info -irce-print-changed-loops -passes=irce -S < %s 2>&1 | FileCheck %s2; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -S < %s 2>&1 | FileCheck %s3 4; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>5; CHECK: irce: in function test_01u: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>6; CHECK-NOT: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>7; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>8; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>9; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>10; CHECK-NOT: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>11; CHECK: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>12; CHECK-NOT: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>13 14; Show that IRCE can turn 'ne' condition to 'slt' in increasing IV when the IV15; can be negative at some point.16define void @test_01(ptr %arr, ptr %a_len_ptr) #0 {17 18; CHECK: test_0119; CHECK: main.exit.selector:20; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]21; CHECK-NEXT: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], 10022; CHECK-NEXT: br i1 [[COND]]23 24entry:25 %len = load i32, ptr %a_len_ptr, !range !026 br label %loop27 28loop:29 %idx = phi i32 [ -3, %entry ], [ %idx.next, %in.bounds ]30 %idx.next = add i32 %idx, 131 %abc = icmp slt i32 %idx, %len32 br i1 %abc, label %in.bounds, label %out.of.bounds33 34in.bounds:35 %addr = getelementptr i32, ptr %arr, i32 %idx36 store i32 0, ptr %addr37 %next = icmp ne i32 %idx.next, 10038 br i1 %next, label %loop, label %exit39 40out.of.bounds:41 ret void42 43exit:44 ret void45}46 47; Show that IRCE can turn 'ne' condition to 'ult' in increasing IV when IV is48; non-negative.49define void @test_01u(ptr %arr, ptr %a_len_ptr) #0 {50 51; CHECK: test_01u52; CHECK: main.exit.selector:53; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]54; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], 10055; CHECK-NEXT: br i1 [[COND]]56 57entry:58 %len = load i32, ptr %a_len_ptr, !range !059 br label %loop60 61loop:62 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]63 %idx.next = add i32 %idx, 164 %abc = icmp slt i32 %idx, %len65 br i1 %abc, label %in.bounds, label %out.of.bounds66 67in.bounds:68 %addr = getelementptr i32, ptr %arr, i32 %idx69 store i32 0, ptr %addr70 %next = icmp ne i32 %idx.next, 10071 br i1 %next, label %loop, label %exit72 73out.of.bounds:74 ret void75 76exit:77 ret void78}79 80; Show that if n is not known to be greater than the starting value, IRCE81; doesn't apply.82define void @test_02(ptr %arr, ptr %a_len_ptr) #0 {83 84; CHECK: test_02(85 86entry:87 %len = load i32, ptr %a_len_ptr, !range !088 br label %loop89 90loop:91 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]92 %idx.next = add i32 %idx, 193 %abc = icmp slt i32 %idx, %len94 br i1 %abc, label %in.bounds, label %out.of.bounds95 96in.bounds:97 %addr = getelementptr i32, ptr %arr, i32 %idx98 store i32 0, ptr %addr99 %next = icmp ne i32 %idx.next, -100100 br i1 %next, label %loop, label %exit101 102out.of.bounds:103 ret void104 105exit:106 ret void107}108 109; Show that IRCE can turn 'eq' condition to 'sge' in increasing IV.110define void @test_03(ptr %arr, ptr %a_len_ptr) #0 {111 112; CHECK: test_03(113; CHECK: main.exit.selector:114; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next, %in.bounds ]115; CHECK-NEXT: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], 100116; CHECK-NEXT: br i1 [[COND]]117 118entry:119 %len = load i32, ptr %a_len_ptr, !range !0120 br label %loop121 122loop:123 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]124 %idx.next = add i32 %idx, 1125 %abc = icmp slt i32 %idx, %len126 br i1 %abc, label %in.bounds, label %out.of.bounds127 128in.bounds:129 %addr = getelementptr i32, ptr %arr, i32 %idx130 store i32 0, ptr %addr131 %next = icmp eq i32 %idx.next, 100132 br i1 %next, label %exit, label %loop133 134out.of.bounds:135 ret void136 137exit:138 ret void139}140 141define void @test_04(ptr %arr, ptr %a_len_ptr) #0 {142 143entry:144 %len = load i32, ptr %a_len_ptr, !range !0145 br label %loop146 147loop:148 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]149 %idx.next = add i32 %idx, 1150 %abc = icmp slt i32 %idx, %len151 br i1 %abc, label %in.bounds, label %out.of.bounds152 153in.bounds:154 %addr = getelementptr i32, ptr %arr, i32 %idx155 store i32 0, ptr %addr156 %next = icmp eq i32 %idx.next, -100157 br i1 %next, label %exit, label %loop158 159out.of.bounds:160 ret void161 162exit:163 ret void164}165 166; Show that IRCE can turn 'ne' condition to 'sgt' in decreasing IV.167define void @test_05(ptr %arr, ptr %a_len_ptr) #0 {168 169; CHECK: test_05(170; CHECK: preloop.exit.selector:171; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ]172; CHECK-NEXT: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0173; CHECK-NEXT: br i1 [[COND]]174 175entry:176 %len = load i32, ptr %a_len_ptr, !range !0177 br label %loop178 179loop:180 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]181 %idx.next = add i32 %idx, -1182 %abc = icmp slt i32 %idx, %len183 br i1 %abc, label %in.bounds, label %out.of.bounds184 185in.bounds:186 %addr = getelementptr i32, ptr %arr, i32 %idx187 store i32 0, ptr %addr188 %next = icmp ne i32 %idx.next, 0189 br i1 %next, label %loop, label %exit190 191out.of.bounds:192 ret void193 194exit:195 ret void196}197 198; Show that IRCE cannot turn 'ne' condition to 'sgt' in decreasing IV if the end199; value is not proved to be less than the start value.200define void @test_06(ptr %arr, ptr %a_len_ptr) #0 {201 202; CHECK: test_06(203 204entry:205 %len = load i32, ptr %a_len_ptr, !range !0206 br label %loop207 208loop:209 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]210 %idx.next = add i32 %idx, -1211 %abc = icmp slt i32 %idx, %len212 br i1 %abc, label %in.bounds, label %out.of.bounds213 214in.bounds:215 %addr = getelementptr i32, ptr %arr, i32 %idx216 store i32 0, ptr %addr217 %next = icmp ne i32 %idx.next, 120218 br i1 %next, label %loop, label %exit219 220out.of.bounds:221 ret void222 223exit:224 ret void225}226 227; Show that IRCE can turn 'eq' condition to 'slt' in decreasing IV.228define void @test_07(ptr %arr, ptr %a_len_ptr) #0 {229 230; CHECK: test_07(231; CHECK: preloop.exit.selector:232; CHECK-NEXT: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %idx.next.preloop, %in.bounds.preloop ]233; CHECK-NEXT: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], 0234; CHECK-NEXT: br i1 [[COND]]235 236entry:237 %len = load i32, ptr %a_len_ptr, !range !0238 br label %loop239 240loop:241 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]242 %idx.next = add i32 %idx, -1243 %abc = icmp slt i32 %idx, %len244 br i1 %abc, label %in.bounds, label %out.of.bounds245 246in.bounds:247 %addr = getelementptr i32, ptr %arr, i32 %idx248 store i32 0, ptr %addr249 %next = icmp eq i32 %idx.next, 0250 br i1 %next, label %exit, label %loop251 252out.of.bounds:253 ret void254 255exit:256 ret void257}258 259; Show that IRCE cannot turn 'eq' condition to 'slt' in decreasing IV if the end260; value is not proved to be less than the start value.261define void @test_08(ptr %arr, ptr %a_len_ptr) #0 {262 263; CHECK: test_08(264 265entry:266 %len = load i32, ptr %a_len_ptr, !range !0267 br label %loop268 269loop:270 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]271 %idx.next = add i32 %idx, -1272 %abc = icmp slt i32 %idx, %len273 br i1 %abc, label %in.bounds, label %out.of.bounds274 275in.bounds:276 %addr = getelementptr i32, ptr %arr, i32 %idx277 store i32 0, ptr %addr278 %next = icmp eq i32 %idx.next, 120279 br i1 %next, label %exit, label %loop280 281out.of.bounds:282 ret void283 284exit:285 ret void286}287 288!0 = !{i32 0, i32 50}289