1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -indvars -S | FileCheck %s 3 4define void @test1() nounwind { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: br label [[BB:%.*]] 8; CHECK: bb: 9; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[DOTINT:%.*]], [[BB]] ] 10; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to double 11; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[INDVAR_CONV]]) [[ATTR0:#.*]] 12; CHECK-NEXT: [[DOTINT]] = add nuw nsw i32 [[IV_INT]], 1 13; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[DOTINT]], 10000 14; CHECK-NEXT: br i1 [[TMP1]], label [[BB]], label [[RETURN:%.*]] 15; CHECK: return: 16; CHECK-NEXT: ret void 17; 18entry: 19 br label %bb 20 21bb: ; preds = %bb, %entry 22 %iv = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] 23 %0 = tail call i32 @foo(double %iv) nounwind 24 %1 = fadd double %iv, 1.000000e+00 25 %2 = fcmp olt double %1, 1.000000e+04 26 br i1 %2, label %bb, label %return 27 28return: ; preds = %bb 29 ret void 30} 31 32declare i32 @foo(double) 33 34define void @test2() nounwind { 35; CHECK-LABEL: @test2( 36; CHECK-NEXT: entry: 37; CHECK-NEXT: br label [[BB:%.*]] 38; CHECK: bb: 39; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ -10, [[ENTRY:%.*]] ], [ [[DOTINT:%.*]], [[BB]] ] 40; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to double 41; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[INDVAR_CONV]]) [[ATTR0]] 42; CHECK-NEXT: [[DOTINT]] = add nsw i32 [[IV_INT]], 2 43; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[DOTINT]], -1 44; CHECK-NEXT: br i1 [[TMP1]], label [[BB]], label [[RETURN:%.*]] 45; CHECK: return: 46; CHECK-NEXT: ret void 47; 48entry: 49 br label %bb 50 51bb: ; preds = %bb, %entry 52 %iv = phi double [ -10.000000e+00, %entry ], [ %1, %bb ] 53 %0 = tail call i32 @foo(double %iv) nounwind 54 %1 = fadd double %iv, 2.000000e+00 55 %2 = fcmp olt double %1, -1.000000e+00 56 br i1 %2, label %bb, label %return 57 58return: ; preds = %bb 59 ret void 60} 61 62 63define void @test3() nounwind { 64; CHECK-LABEL: @test3( 65; CHECK-NEXT: entry: 66; CHECK-NEXT: br label [[BB:%.*]] 67; CHECK: bb: 68; CHECK-NEXT: [[IV:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[BB]] ] 69; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[IV]]) [[ATTR0]] 70; CHECK-NEXT: [[TMP1]] = fadd double [[IV]], 1.000000e+00 71; CHECK-NEXT: br i1 false, label [[BB]], label [[RETURN:%.*]] 72; CHECK: return: 73; CHECK-NEXT: ret void 74; 75entry: 76 br label %bb 77 78bb: ; preds = %bb, %entry 79 %iv = phi double [ 0.000000e+00, %entry ], [ %1, %bb ] 80 %0 = tail call i32 @foo(double %iv) nounwind 81 %1 = fadd double %iv, 1.000000e+00 82 %2 = fcmp olt double %1, -1.000000e+00 83 br i1 %2, label %bb, label %return 84 85return: 86 ret void 87} 88 89define void @test4() nounwind { 90; CHECK-LABEL: @test4( 91; CHECK-NEXT: entry: 92; CHECK-NEXT: br label [[BB:%.*]] 93; CHECK: bb: 94; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 40, [[ENTRY:%.*]] ], [ [[DOTINT:%.*]], [[BB]] ] 95; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to double 96; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[INDVAR_CONV]]) [[ATTR0]] 97; CHECK-NEXT: [[DOTINT]] = add nsw i32 [[IV_INT]], -1 98; CHECK-NEXT: br i1 false, label [[BB]], label [[RETURN:%.*]] 99; CHECK: return: 100; CHECK-NEXT: ret void 101; 102entry: 103 br label %bb 104 105bb: ; preds = %bb, %entry 106 %iv = phi double [ 40.000000e+00, %entry ], [ %1, %bb ] 107 %0 = tail call i32 @foo(double %iv) nounwind 108 %1 = fadd double %iv, -1.000000e+00 109 %2 = fcmp olt double %1, 1.000000e+00 110 br i1 %2, label %bb, label %return 111 112return: 113 ret void 114} 115 116; PR6761 117define void @test5() nounwind { 118; <label>:0 119; CHECK-LABEL: @test5( 120; CHECK-NEXT: br label [[TMP1:%.*]] 121; CHECK: 1: 122; CHECK-NEXT: [[DOTINT:%.*]] = phi i32 [ 9, [[TMP0:%.*]] ], [ [[DOTINT1:%.*]], [[TMP1]] ] 123; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @foo(double 0.000000e+00) 124; CHECK-NEXT: [[DOTINT1]] = add nsw i32 [[DOTINT]], -1 125; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[DOTINT1]], 0 126; CHECK-NEXT: br i1 [[TMP3]], label [[EXIT:%.*]], label [[TMP1]] 127; CHECK: exit: 128; CHECK-NEXT: ret void 129; 130 br label %1 131 132; <label>:1 133 %2 = phi double [ 9.000000e+00, %0 ], [ %4, %1 ] 134 %3 = tail call i32 @foo(double 0.0) 135 %4 = fadd double %2, -1.000000e+00 136 %5 = fcmp ult double %4, 0.000000e+00 137 br i1 %5, label %exit, label %1 138 139exit: 140 ret void 141} 142 143define double @test_max_be() { 144; CHECK-LABEL: @test_max_be( 145; CHECK-NEXT: bb4: 146; CHECK-NEXT: br label [[BB8:%.*]] 147; CHECK: bb8: 148; CHECK-NEXT: [[TMP10:%.*]] = phi double [ 0.000000e+00, [[BB4:%.*]] ], [ [[TMP12:%.*]], [[BB22:%.*]] ] 149; CHECK-NEXT: [[TMP11_INT:%.*]] = phi i32 [ 0, [[BB4]] ], [ [[TMP13_INT:%.*]], [[BB22]] ] 150; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to double 151; CHECK-NEXT: [[TMP12]] = fadd double [[TMP10]], [[INDVAR_CONV]] 152; CHECK-NEXT: [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1 153; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999 154; CHECK-NEXT: br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]] 155; CHECK: bb22: 156; CHECK-NEXT: br i1 true, label [[BB8]], label [[BB6]] 157; CHECK: bb6: 158; CHECK-NEXT: [[TMP12_LCSSA:%.*]] = phi double [ [[TMP12]], [[BB22]] ], [ [[TMP12]], [[BB8]] ] 159; CHECK-NEXT: ret double [[TMP12_LCSSA]] 160; 161bb4: 162 br label %bb8 163 164bb8: 165 %tmp9 = phi i64 [ 1, %bb4 ], [ %tmp23, %bb22 ] 166 %tmp10 = phi double [ 0.000000e+00, %bb4 ], [ %tmp12, %bb22 ] 167 %tmp11 = phi double [ 0.000000e+00, %bb4 ], [ %tmp13, %bb22 ] 168 %tmp12 = fadd double %tmp10, %tmp11 169 %tmp13 = fadd double %tmp11, 1.000000e+00 170 %tmp14 = fcmp olt double %tmp13, 9.999900e+04 171 br i1 %tmp14, label %bb22, label %bb6 172 173bb22: 174 %tmp23 = add nuw nsw i64 %tmp9, 1 175 %tmp24 = icmp ult i64 %tmp9, 1048576 176 br i1 %tmp24, label %bb8, label %bb6 177 178bb6: 179 ret double %tmp12 180} 181 182define float @test_max_be2() { 183; CHECK-LABEL: @test_max_be2( 184; CHECK-NEXT: bb4: 185; CHECK-NEXT: br label [[BB8:%.*]] 186; CHECK: bb8: 187; CHECK-NEXT: [[TMP10:%.*]] = phi float [ 0.000000e+00, [[BB4:%.*]] ], [ [[TMP12:%.*]], [[BB22:%.*]] ] 188; CHECK-NEXT: [[TMP11_INT:%.*]] = phi i32 [ 0, [[BB4]] ], [ [[TMP13_INT:%.*]], [[BB22]] ] 189; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to float 190; CHECK-NEXT: [[TMP12]] = fadd float [[TMP10]], [[INDVAR_CONV]] 191; CHECK-NEXT: [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1 192; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999 193; CHECK-NEXT: br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]] 194; CHECK: bb22: 195; CHECK-NEXT: br i1 true, label [[BB8]], label [[BB6]] 196; CHECK: bb6: 197; CHECK-NEXT: [[TMP12_LCSSA:%.*]] = phi float [ [[TMP12]], [[BB22]] ], [ [[TMP12]], [[BB8]] ] 198; CHECK-NEXT: ret float [[TMP12_LCSSA]] 199; 200bb4: 201 br label %bb8 202 203bb8: 204 %tmp9 = phi i64 [ 1, %bb4 ], [ %tmp23, %bb22 ] 205 %tmp10 = phi float [ 0.000000e+00, %bb4 ], [ %tmp12, %bb22 ] 206 %tmp11 = phi float [ 0.000000e+00, %bb4 ], [ %tmp13, %bb22 ] 207 %tmp12 = fadd float %tmp10, %tmp11 208 %tmp13 = fadd float %tmp11, 1.000000e+00 209 %tmp14 = fcmp olt float %tmp13, 9.999900e+04 210 br i1 %tmp14, label %bb22, label %bb6 211 212bb22: 213 %tmp23 = add nuw nsw i64 %tmp9, 1 214 %tmp24 = icmp ult i64 %tmp9, 1048576 215 br i1 %tmp24, label %bb8, label %bb6 216 217bb6: 218 ret float %tmp12 219} 220 221; Bounds check 222define float @test_max_be3() { 223; CHECK-LABEL: @test_max_be3( 224; CHECK-NEXT: bb4: 225; CHECK-NEXT: br label [[BB8:%.*]] 226; CHECK: bb8: 227; CHECK-NEXT: [[TMP10:%.*]] = phi float [ 0.000000e+00, [[BB4:%.*]] ], [ [[TMP12:%.*]], [[BB22:%.*]] ] 228; CHECK-NEXT: [[TMP11_INT:%.*]] = phi i32 [ 0, [[BB4]] ], [ [[TMP13_INT:%.*]], [[BB22]] ] 229; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[TMP11_INT]] to float 230; CHECK-NEXT: [[TMP12]] = fadd float [[TMP10]], [[INDVAR_CONV]] 231; CHECK-NEXT: [[TMP13_INT]] = add nuw nsw i32 [[TMP11_INT]], 1 232; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i32 [[TMP13_INT]], 99999 233; CHECK-NEXT: br i1 [[TMP14]], label [[BB22]], label [[BB6:%.*]] 234; CHECK: bb22: 235; CHECK-NEXT: br i1 true, label [[BB8]], label [[BB6]] 236; CHECK: bb6: 237; CHECK-NEXT: [[TMP12_LCSSA:%.*]] = phi float [ [[TMP12]], [[BB22]] ], [ [[TMP12]], [[BB8]] ] 238; CHECK-NEXT: ret float [[TMP12_LCSSA]] 239; 240bb4: 241 br label %bb8 242 243bb8: 244 %tmp9 = phi i64 [ 1, %bb4 ], [ %tmp23, %bb22 ] 245 %tmp10 = phi float [ 0.000000e+00, %bb4 ], [ %tmp12, %bb22 ] 246 %tmp11 = phi float [ 0.000000e+00, %bb4 ], [ %tmp13, %bb22 ] 247 %tmp12 = fadd float %tmp10, %tmp11 248 %tmp13 = fadd float %tmp11, 1.000000e+00 249 %tmp14 = fcmp olt float %tmp13, 9.999900e+04 250 br i1 %tmp14, label %bb22, label %bb6 251 252bb22: 253 %tmp23 = add nuw nsw i64 %tmp9, 1 254 ;; 2^23 = 16777215 255 %tmp24 = icmp ult i64 %tmp9, 16777215 256 br i1 %tmp24, label %bb8, label %bb6 257 258bb6: 259 ret float %tmp12 260} 261 262 263; Show that given a computeable exit count, we can remove an 264; fcmp of a casted integer IV. (TODO) 265define void @fcmp1() nounwind { 266; CHECK-LABEL: @fcmp1( 267; CHECK-NEXT: entry: 268; CHECK-NEXT: br label [[BB:%.*]] 269; CHECK: bb: 270; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 271; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], 20000 272; CHECK-NEXT: br i1 [[CMP1]], label [[BACKEDGE]], label [[RETURN:%.*]] 273; CHECK: backedge: 274; CHECK-NEXT: [[IV_FP:%.*]] = sitofp i64 [[IV]] to double 275; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[IV_FP]]) [[ATTR0]] 276; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 277; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt double [[IV_FP]], 1.000000e+04 278; CHECK-NEXT: br i1 [[CMP2]], label [[BB]], label [[RETURN]] 279; CHECK: return: 280; CHECK-NEXT: ret void 281; 282entry: 283 br label %bb 284 285bb: ; preds = %bb, %entry 286 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] 287 %cmp1 = icmp slt i64 %iv, 20000 288 br i1 %cmp1, label %backedge, label %return 289 290backedge: 291 %iv.fp = sitofp i64 %iv to double 292 tail call i32 @foo(double %iv.fp) nounwind 293 %iv.next = add nsw nuw i64 %iv, 1 294 %cmp2 = fcmp olt double %iv.fp, 1.000000e+04 295 br i1 %cmp2, label %bb, label %return 296 297return: ; preds = %bb 298 ret void 299} 300 301define void @fcmp2() nounwind { 302; CHECK-LABEL: @fcmp2( 303; CHECK-NEXT: entry: 304; CHECK-NEXT: br label [[BB:%.*]] 305; CHECK: bb: 306; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 307; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], 2000 308; CHECK-NEXT: br i1 [[CMP1]], label [[BACKEDGE]], label [[RETURN:%.*]] 309; CHECK: backedge: 310; CHECK-NEXT: [[IV_FP:%.*]] = sitofp i64 [[IV]] to double 311; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[IV_FP]]) [[ATTR0]] 312; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 313; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt double [[IV_FP]], 1.000000e+04 314; CHECK-NEXT: br i1 [[CMP2]], label [[BB]], label [[RETURN]] 315; CHECK: return: 316; CHECK-NEXT: ret void 317; 318entry: 319 br label %bb 320 321bb: ; preds = %bb, %entry 322 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] 323 %cmp1 = icmp slt i64 %iv, 2000 324 br i1 %cmp1, label %backedge, label %return 325 326backedge: 327 %iv.fp = sitofp i64 %iv to double 328 tail call i32 @foo(double %iv.fp) nounwind 329 %iv.next = add nsw nuw i64 %iv, 1 330 %cmp2 = fcmp olt double %iv.fp, 1.000000e+04 331 br i1 %cmp2, label %bb, label %return 332 333return: ; preds = %bb 334 ret void 335} 336 337define void @fcmp_neg1() nounwind { 338; CHECK-LABEL: @fcmp_neg1( 339; CHECK-NEXT: entry: 340; CHECK-NEXT: br label [[BB:%.*]] 341; CHECK: bb: 342; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 343; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], -20 344; CHECK-NEXT: br i1 [[CMP1]], label [[BACKEDGE]], label [[RETURN:%.*]] 345; CHECK: backedge: 346; CHECK-NEXT: [[IV_FP:%.*]] = sitofp i64 [[IV]] to double 347; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[IV_FP]]) [[ATTR0]] 348; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 349; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt double [[IV_FP]], 1.000000e+04 350; CHECK-NEXT: br i1 [[CMP2]], label [[BB]], label [[RETURN]] 351; CHECK: return: 352; CHECK-NEXT: ret void 353; 354entry: 355 br label %bb 356 357bb: ; preds = %bb, %entry 358 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ] 359 ;; Range fact outside precise integer region 360 %cmp1 = icmp ult i64 %iv, -20 361 br i1 %cmp1, label %backedge, label %return 362 363backedge: 364 %iv.fp = sitofp i64 %iv to double 365 tail call i32 @foo(double %iv.fp) nounwind 366 %iv.next = add nuw i64 %iv, 1 367 %cmp2 = fcmp olt double %iv.fp, 1.000000e+04 368 br i1 %cmp2, label %bb, label %return 369 370return: ; preds = %bb 371 ret void 372} 373