1; RUN: opt -irce -S -verify-loop-info -irce-print-changed-loops -irce-skip-profitability-checks < %s 2>&1 | FileCheck %s 2 3; CHECK: irce: in function test_inc_eq: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> 4; CHECK: irce: in function test_inc_ne: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> 5; CHECK: irce: in function test_inc_slt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> 6; CHECK: irce: in function test_inc_ult: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting> 7; CHECK: irce: in function signed_var_imm_dec_sgt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> 8; CHECK-NOT: irce: in function signed_var_imm_dec_slt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> 9; CHECK: irce: in function signed_var_imm_dec_sge: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> 10; CHECK: irce: in function signed_var_imm_dec_ne: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> 11; CHECK-NOT: irce: in function signed_var_imm_dec_eq: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting> 12 13; CHECK-LABEL: test_inc_eq( 14; CHECK: main.exit.selector: 15; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] 16; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N 17; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit 18define void @test_inc_eq(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { 19entry: 20 %cmp16 = icmp sgt i32 %N, 0 21 br i1 %cmp16, label %for.body, label %for.cond.cleanup 22 23for.cond.cleanup: 24 ret void 25 26for.body: 27 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 28 %cmp1 = icmp ult i32 %i.017, 512 29 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 30 %0 = load i32, i32* %arrayidx, align 4 31 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 32 %1 = load i32, i32* %arrayidx2, align 4 33 br i1 %cmp1, label %if.then, label %if.else 34 35if.then: 36 %sub = sub i32 %0, %1 37 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 38 %2 = load i32, i32* %arrayidx3, align 4 39 %add = add nsw i32 %sub, %2 40 store i32 %add, i32* %arrayidx3, align 4 41 br label %for.inc 42 43if.else: 44 %add6 = add nsw i32 %1, %0 45 %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 46 store i32 %add6, i32* %arrayidx7, align 4 47 br label %for.inc 48 49for.inc: 50 %inc = add nuw nsw i32 %i.017, 1 51 %exitcond = icmp eq i32 %inc, %N 52 br i1 %exitcond, label %for.cond.cleanup, label %for.body 53} 54 55; CHECK-LABEL: test_inc_ne 56; CHECK: main.exit.selector: 57; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] 58; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N 59; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit 60define void @test_inc_ne(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { 61entry: 62 %cmp16 = icmp sgt i32 %N, 0 63 br i1 %cmp16, label %for.body, label %for.cond.cleanup 64 65for.cond.cleanup: 66 ret void 67 68for.body: 69 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 70 %cmp1 = icmp ult i32 %i.017, 512 71 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 72 %0 = load i32, i32* %arrayidx, align 4 73 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 74 %1 = load i32, i32* %arrayidx2, align 4 75 br i1 %cmp1, label %if.then, label %if.else 76 77if.then: 78 %sub = sub i32 %0, %1 79 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 80 %2 = load i32, i32* %arrayidx3, align 4 81 %add = add nsw i32 %sub, %2 82 store i32 %add, i32* %arrayidx3, align 4 83 br label %for.inc 84 85if.else: 86 %add6 = add nsw i32 %1, %0 87 %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 88 store i32 %add6, i32* %arrayidx7, align 4 89 br label %for.inc 90 91for.inc: 92 %inc = add nuw nsw i32 %i.017, 1 93 %exitcond = icmp ne i32 %inc, %N 94 br i1 %exitcond, label %for.body, label %for.cond.cleanup 95} 96 97; CHECK-LABEL: test_inc_slt( 98; CHECK: main.exit.selector: 99; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] 100; CHECK: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], %N 101; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit 102define void @test_inc_slt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { 103entry: 104 %cmp16 = icmp sgt i32 %N, 0 105 br i1 %cmp16, label %for.body, label %for.cond.cleanup 106 107for.cond.cleanup: 108 ret void 109 110for.body: 111 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 112 %cmp1 = icmp ult i32 %i.017, 512 113 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 114 %0 = load i32, i32* %arrayidx, align 4 115 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 116 %1 = load i32, i32* %arrayidx2, align 4 117 br i1 %cmp1, label %if.then, label %if.else 118 119if.then: 120 %sub = sub i32 %0, %1 121 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 122 %2 = load i32, i32* %arrayidx3, align 4 123 %add = add nsw i32 %sub, %2 124 store i32 %add, i32* %arrayidx3, align 4 125 br label %for.inc 126 127if.else: 128 %add6 = add nsw i32 %1, %0 129 %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 130 store i32 %add6, i32* %arrayidx7, align 4 131 br label %for.inc 132 133for.inc: 134 %inc = add nuw nsw i32 %i.017, 1 135 %exitcond = icmp slt i32 %inc, %N 136 br i1 %exitcond, label %for.body, label %for.cond.cleanup 137} 138 139; CHECK-LABEL: test_inc_ult 140; CHECK: main.exit.selector: 141; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ] 142; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N 143; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit 144define void @test_inc_ult(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { 145entry: 146 %cmp16 = icmp ugt i32 %N, 0 147 br i1 %cmp16, label %for.body, label %for.cond.cleanup 148 149for.cond.cleanup: 150 ret void 151 152for.body: 153 %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 154 %cmp1 = icmp ult i32 %i.017, 512 155 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017 156 %0 = load i32, i32* %arrayidx, align 4 157 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017 158 %1 = load i32, i32* %arrayidx2, align 4 159 br i1 %cmp1, label %if.then, label %if.else 160 161if.then: 162 %sub = sub i32 %0, %1 163 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017 164 %2 = load i32, i32* %arrayidx3, align 4 165 %add = add nsw i32 %sub, %2 166 store i32 %add, i32* %arrayidx3, align 4 167 br label %for.inc 168 169if.else: 170 %add6 = add nsw i32 %1, %0 171 %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017 172 store i32 %add6, i32* %arrayidx7, align 4 173 br label %for.inc 174 175for.inc: 176 %inc = add nuw nsw i32 %i.017, 1 177 %exitcond = icmp ult i32 %inc, %N 178 br i1 %exitcond, label %for.body, label %for.cond.cleanup 179} 180 181; CHECK-LABEL: signed_var_imm_dec_sgt( 182; CHECK: main.exit.selector: 183; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %dec, %for.inc ] 184; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M 185; CHECK: br i1 [[COND]] 186define void @signed_var_imm_dec_sgt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { 187entry: 188 %cmp14 = icmp slt i32 %M, 1024 189 br i1 %cmp14, label %for.body, label %for.cond.cleanup 190 191for.cond.cleanup: ; preds = %for.inc, %entry 192 ret void 193 194for.body: ; preds = %entry, %for.inc 195 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 196 %cmp1 = icmp slt i32 %iv, 1024 197 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv 198 %0 = load i32, i32* %arrayidx, align 4 199 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv 200 %1 = load i32, i32* %arrayidx2, align 4 201 %mul = mul nsw i32 %1, %0 202 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv 203 br i1 %cmp1, label %for.inc, label %if.else 204 205if.else: ; preds = %for.body 206 %2 = load i32, i32* %arrayidx3, align 4 207 %add = add nsw i32 %2, %mul 208 br label %for.inc 209 210for.inc: ; preds = %for.body, %if.else 211 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 212 store i32 %storemerge, i32* %arrayidx3, align 4 213 %dec = add nsw i32 %iv, -1 214 %cmp = icmp sgt i32 %dec, %M 215 br i1 %cmp, label %for.body, label %for.cond.cleanup 216} 217 218; CHECK-LABEL: signed_var_imm_dec_sge( 219; CHECK: main.exit.selector: ; preds = %for.inc 220; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %iv, %for.inc ] 221; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M 222; CHECK: br i1 [[COND]] 223define void @signed_var_imm_dec_sge(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { 224entry: 225 %cmp14 = icmp sgt i32 %M, 1024 226 br i1 %cmp14, label %for.cond.cleanup, label %for.body 227 228for.cond.cleanup: ; preds = %for.inc, %entry 229 ret void 230 231for.body: ; preds = %entry, %for.inc 232 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 233 %cmp1 = icmp slt i32 %iv, 1024 234 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv 235 %0 = load i32, i32* %arrayidx, align 4 236 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv 237 %1 = load i32, i32* %arrayidx2, align 4 238 %mul = mul nsw i32 %1, %0 239 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv 240 br i1 %cmp1, label %for.inc, label %if.else 241 242if.else: ; preds = %for.body 243 %2 = load i32, i32* %arrayidx3, align 4 244 %add = add nsw i32 %2, %mul 245 br label %for.inc 246 247for.inc: ; preds = %for.body, %if.else 248 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 249 store i32 %storemerge, i32* %arrayidx3, align 4 250 %dec = add nsw i32 %iv, -1 251 %cmp = icmp sgt i32 %iv, %M 252 br i1 %cmp, label %for.body, label %for.cond.cleanup 253} 254 255define void @signed_var_imm_dec_slt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { 256entry: 257 %cmp14 = icmp sgt i32 %M, 1024 258 br i1 %cmp14, label %for.cond.cleanup, label %for.body 259 260for.cond.cleanup: ; preds = %for.inc, %entry 261 ret void 262 263for.body: ; preds = %entry, %for.inc 264 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 265 %cmp1 = icmp slt i32 %iv, 1024 266 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv 267 %0 = load i32, i32* %arrayidx, align 4 268 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv 269 %1 = load i32, i32* %arrayidx2, align 4 270 %mul = mul nsw i32 %1, %0 271 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv 272 br i1 %cmp1, label %for.inc, label %if.else 273 274if.else: ; preds = %for.body 275 %2 = load i32, i32* %arrayidx3, align 4 276 %add = add nsw i32 %2, %mul 277 br label %for.inc 278 279for.inc: ; preds = %for.body, %if.else 280 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 281 store i32 %storemerge, i32* %arrayidx3, align 4 282 %dec = add nsw i32 %iv, -1 283 %cmp = icmp slt i32 %iv, %M 284 br i1 %cmp, label %for.cond.cleanup, label %for.body 285} 286 287; CHECK-LABEL: signed_var_imm_dec_ne( 288; CHECK: main.exit.selector: ; preds = %for.inc 289; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %dec, %for.inc ] 290; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M 291; CHECK: br i1 [[COND]] 292define void @signed_var_imm_dec_ne(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { 293entry: 294 %cmp14 = icmp slt i32 %M, 1024 295 br i1 %cmp14, label %for.body, label %for.cond.cleanup 296 297for.cond.cleanup: ; preds = %for.inc, %entry 298 ret void 299 300for.body: ; preds = %entry, %for.inc 301 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 302 %cmp1 = icmp slt i32 %iv, 1024 303 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv 304 %0 = load i32, i32* %arrayidx, align 4 305 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv 306 %1 = load i32, i32* %arrayidx2, align 4 307 %mul = mul nsw i32 %1, %0 308 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv 309 br i1 %cmp1, label %for.inc, label %if.else 310 311if.else: ; preds = %for.body 312 %2 = load i32, i32* %arrayidx3, align 4 313 %add = add nsw i32 %2, %mul 314 br label %for.inc 315 316for.inc: ; preds = %for.body, %if.else 317 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 318 store i32 %storemerge, i32* %arrayidx3, align 4 319 %dec = add nsw i32 %iv, -1 320 %cmp = icmp ne i32 %dec, %M 321 br i1 %cmp, label %for.body, label %for.cond.cleanup 322} 323 324define void @signed_var_imm_dec_eq(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) { 325entry: 326 %cmp14 = icmp slt i32 %M, 1024 327 br i1 %cmp14, label %for.body, label %for.cond.cleanup 328 329for.cond.cleanup: ; preds = %for.inc, %entry 330 ret void 331 332for.body: ; preds = %entry, %for.inc 333 %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ] 334 %cmp1 = icmp slt i32 %iv, 1024 335 %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv 336 %0 = load i32, i32* %arrayidx, align 4 337 %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv 338 %1 = load i32, i32* %arrayidx2, align 4 339 %mul = mul nsw i32 %1, %0 340 %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv 341 br i1 %cmp1, label %for.inc, label %if.else 342 343if.else: ; preds = %for.body 344 %2 = load i32, i32* %arrayidx3, align 4 345 %add = add nsw i32 %2, %mul 346 br label %for.inc 347 348for.inc: ; preds = %for.body, %if.else 349 %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ] 350 store i32 %storemerge, i32* %arrayidx3, align 4 351 %dec = add nsw i32 %iv, -1 352 %cmp = icmp eq i32 %dec, %M 353 br i1 %cmp, label %for.cond.cleanup, label %for.body 354} 355