1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=indvars -S | FileCheck %s 3 4@A = external global i32 5 6define void @add_cr_nsw_nuw() { 7; CHECK-LABEL: @add_cr_nsw_nuw( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br label [[LOOP:%.*]] 10; CHECK: loop: 11; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 12; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 13; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 14; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1000 15; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 16; CHECK: loopexit: 17; CHECK-NEXT: ret void 18; 19entry: 20 br label %loop 21 22loop: 23 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 24 %i.next = add i32 %i, 1 25 store i32 %i, ptr @A 26 %c = icmp ne i32 %i.next, 1000 27 br i1 %c, label %loop, label %loopexit 28 29loopexit: 30 ret void 31} 32 33define void @add_cr_nuw() { 34; CHECK-LABEL: @add_cr_nuw( 35; CHECK-NEXT: entry: 36; CHECK-NEXT: br label [[LOOP:%.*]] 37; CHECK: loop: 38; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 39; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 40; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 41; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], -1 42; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 43; CHECK: loopexit: 44; CHECK-NEXT: ret void 45; 46entry: 47 br label %loop 48 49loop: 50 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 51 %i.next = add i32 %i, 1 52 store i32 %i, ptr @A 53 %c = icmp ne i32 %i.next, -1 54 br i1 %c, label %loop, label %loopexit 55 56loopexit: 57 ret void 58} 59 60define void @add_cr_nsw() { 61; CHECK-LABEL: @add_cr_nsw( 62; CHECK-NEXT: entry: 63; CHECK-NEXT: br label [[LOOP:%.*]] 64; CHECK: loop: 65; CHECK-NEXT: [[I:%.*]] = phi i32 [ -10, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 66; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 67; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 68; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 10 69; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 70; CHECK: loopexit: 71; CHECK-NEXT: ret void 72; 73entry: 74 br label %loop 75 76loop: 77 %i = phi i32 [ -10, %entry ], [ %i.next, %loop ] 78 %i.next = add i32 %i, 1 79 store i32 %i, ptr @A 80 %c = icmp ne i32 %i.next, 10 81 br i1 %c, label %loop, label %loopexit 82 83loopexit: 84 ret void 85} 86 87define void @add_cr_none() { 88; CHECK-LABEL: @add_cr_none( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: br label [[LOOP:%.*]] 91; CHECK: loop: 92; CHECK-NEXT: [[I:%.*]] = phi i32 [ 10, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 93; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 94; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 95; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0 96; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 97; CHECK: loopexit: 98; CHECK-NEXT: ret void 99; 100entry: 101 br label %loop 102 103loop: 104 %i = phi i32 [ 10, %entry ], [ %i.next, %loop ] 105 %i.next = add i32 %i, 1 106 store i32 %i, ptr @A 107 %c = icmp ne i32 %i.next, 0 108 br i1 %c, label %loop, label %loopexit 109 110loopexit: 111 ret void 112} 113 114define void @add_unknown_none(i32 %n) { 115; CHECK-LABEL: @add_unknown_none( 116; CHECK-NEXT: entry: 117; CHECK-NEXT: br label [[LOOP:%.*]] 118; CHECK: loop: 119; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 120; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 121; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 122; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], [[N:%.*]] 123; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 124; CHECK: loopexit: 125; CHECK-NEXT: ret void 126; 127entry: 128 br label %loop 129 130loop: 131 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 132 %i.next = add i32 %i, 1 133 store i32 %i, ptr @A 134 %c = icmp ne i32 %i.next, %n 135 br i1 %c, label %loop, label %loopexit 136 137loopexit: 138 ret void 139} 140 141define void @sub_cr_nsw_nuw() { 142; CHECK-LABEL: @sub_cr_nsw_nuw( 143; CHECK-NEXT: entry: 144; CHECK-NEXT: br label [[LOOP:%.*]] 145; CHECK: loop: 146; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 147; CHECK-NEXT: [[I_NEXT]] = sub nsw i32 [[I]], -1 148; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 149; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1000 150; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 151; CHECK: loopexit: 152; CHECK-NEXT: ret void 153; 154entry: 155 br label %loop 156 157loop: 158 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 159 %i.next = sub i32 %i, -1 160 store i32 %i, ptr @A 161 %c = icmp ne i32 %i.next, 1000 162 br i1 %c, label %loop, label %loopexit 163 164loopexit: 165 ret void 166} 167 168 169define void @sub_unknown_none(i32 %n) { 170; CHECK-LABEL: @sub_unknown_none( 171; CHECK-NEXT: entry: 172; CHECK-NEXT: br label [[LOOP:%.*]] 173; CHECK: loop: 174; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 175; CHECK-NEXT: [[I_NEXT]] = sub i32 [[I]], -1 176; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 177; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], [[N:%.*]] 178; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 179; CHECK: loopexit: 180; CHECK-NEXT: ret void 181; 182entry: 183 br label %loop 184 185loop: 186 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 187 %i.next = sub i32 %i, -1 188 store i32 %i, ptr @A 189 %c = icmp ne i32 %i.next, %n 190 br i1 %c, label %loop, label %loopexit 191 192loopexit: 193 ret void 194} 195 196 197; NOTE: For the rest of these, it looks like we're failing to use a statically 198; computable backedge taken count to infer a range on the IV and thus fail to 199; prove flags via constant range reasoning. 200 201; TODO 202define void @mul_cr_nsw_nuw() { 203; CHECK-LABEL: @mul_cr_nsw_nuw( 204; CHECK-NEXT: entry: 205; CHECK-NEXT: br label [[LOOP:%.*]] 206; CHECK: loop: 207; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 208; CHECK-NEXT: [[I_NEXT]] = mul i32 [[I]], 2 209; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 210; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1024 211; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 212; CHECK: loopexit: 213; CHECK-NEXT: ret void 214; 215entry: 216 br label %loop 217 218loop: 219 %i = phi i32 [ 1, %entry ], [ %i.next, %loop ] 220 %i.next = mul i32 %i, 2 221 store i32 %i, ptr @A 222 %c = icmp ne i32 %i.next, 1024 223 br i1 %c, label %loop, label %loopexit 224 225loopexit: 226 ret void 227} 228 229;; TODO 230define void @shl_cr_nsw_nuw() { 231; CHECK-LABEL: @shl_cr_nsw_nuw( 232; CHECK-NEXT: entry: 233; CHECK-NEXT: br label [[LOOP:%.*]] 234; CHECK: loop: 235; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 236; CHECK-NEXT: [[I_NEXT]] = shl i32 [[I]], 1 237; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 238; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1024 239; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 240; CHECK: loopexit: 241; CHECK-NEXT: ret void 242; 243entry: 244 br label %loop 245 246loop: 247 %i = phi i32 [ 1, %entry ], [ %i.next, %loop ] 248 %i.next = shl i32 %i, 1 249 store i32 %i, ptr @A 250 %c = icmp ne i32 %i.next, 1024 251 br i1 %c, label %loop, label %loopexit 252 253loopexit: 254 ret void 255} 256 257; TODO 258define void @lshr_cr_nsw_nuw() { 259; CHECK-LABEL: @lshr_cr_nsw_nuw( 260; CHECK-NEXT: entry: 261; CHECK-NEXT: br label [[LOOP:%.*]] 262; CHECK: loop: 263; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 264; CHECK-NEXT: [[I_NEXT]] = lshr i32 [[I]], 1 265; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 266; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0 267; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 268; CHECK: loopexit: 269; CHECK-NEXT: ret void 270; 271entry: 272 br label %loop 273 274loop: 275 %i = phi i32 [ 1024, %entry ], [ %i.next, %loop ] 276 %i.next = lshr i32 %i, 1 277 store i32 %i, ptr @A 278 %c = icmp ne i32 %i.next, 0 279 br i1 %c, label %loop, label %loopexit 280 281loopexit: 282 ret void 283} 284 285; TODO 286define void @lshr_cr_nuw() { 287; CHECK-LABEL: @lshr_cr_nuw( 288; CHECK-NEXT: entry: 289; CHECK-NEXT: br label [[LOOP:%.*]] 290; CHECK: loop: 291; CHECK-NEXT: [[I:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 292; CHECK-NEXT: [[I_NEXT]] = lshr i32 [[I]], 1 293; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 294; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0 295; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 296; CHECK: loopexit: 297; CHECK-NEXT: ret void 298; 299entry: 300 br label %loop 301 302loop: 303 %i = phi i32 [ -1, %entry ], [ %i.next, %loop ] 304 %i.next = lshr i32 %i, 1 305 store i32 %i, ptr @A 306 %c = icmp ne i32 %i.next, 0 307 br i1 %c, label %loop, label %loopexit 308 309loopexit: 310 ret void 311} 312 313; TODO 314define void @ashr_cr_nsw_nuw() { 315; CHECK-LABEL: @ashr_cr_nsw_nuw( 316; CHECK-NEXT: entry: 317; CHECK-NEXT: br label [[LOOP:%.*]] 318; CHECK: loop: 319; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 320; CHECK-NEXT: [[I_NEXT]] = ashr i32 [[I]], 1 321; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 322; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0 323; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 324; CHECK: loopexit: 325; CHECK-NEXT: ret void 326; 327entry: 328 br label %loop 329 330loop: 331 %i = phi i32 [ 1024, %entry ], [ %i.next, %loop ] 332 %i.next = ashr i32 %i, 1 333 store i32 %i, ptr @A 334 %c = icmp ne i32 %i.next, 0 335 br i1 %c, label %loop, label %loopexit 336 337loopexit: 338 ret void 339} 340 341; TODO 342define void @ashr_cr_nsw() { 343; CHECK-LABEL: @ashr_cr_nsw( 344; CHECK-NEXT: entry: 345; CHECK-NEXT: br label [[LOOP:%.*]] 346; CHECK: loop: 347; CHECK-NEXT: [[I:%.*]] = phi i32 [ -1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 348; CHECK-NEXT: [[I_NEXT]] = ashr i32 [[I]], 1 349; CHECK-NEXT: store i32 [[I]], ptr @A, align 4 350; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1 351; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]] 352; CHECK: loopexit: 353; CHECK-NEXT: ret void 354; 355entry: 356 br label %loop 357 358loop: 359 %i = phi i32 [ -1024, %entry ], [ %i.next, %loop ] 360 %i.next = ashr i32 %i, 1 361 store i32 %i, ptr @A 362 %c = icmp ne i32 %i.next, 1 363 br i1 %c, label %loop, label %loopexit 364 365loopexit: 366 ret void 367} 368 369 370