1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=indvars < %s | FileCheck %s 3 4; Check that we replace signed comparisons between non-negative values with 5; unsigned comparisons if we can. 6 7target datalayout = "n8:16:32:64" 8 9define i32 @test_01(i32 %a, i32 %b, ptr %p) { 10; CHECK-LABEL: @test_01( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: br label [[LOOP_ENTRY:%.*]] 13; CHECK: loop.entry: 14; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BE:%.*]] ] 15; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[IV]], 100 16; CHECK-NEXT: br i1 [[CMP1]], label [[B1:%.*]], label [[B2:%.*]] 17; CHECK: b1: 18; CHECK-NEXT: store i32 [[IV]], ptr [[P:%.*]], align 4 19; CHECK-NEXT: br label [[MERGE:%.*]] 20; CHECK: b2: 21; CHECK-NEXT: store i32 [[A:%.*]], ptr [[P]], align 4 22; CHECK-NEXT: br label [[MERGE]] 23; CHECK: merge: 24; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[IV]], 100 25; CHECK-NEXT: br i1 [[CMP2]], label [[B3:%.*]], label [[B4:%.*]] 26; CHECK: b3: 27; CHECK-NEXT: store i32 [[IV]], ptr [[P]], align 4 28; CHECK-NEXT: br label [[LOOP_BE]] 29; CHECK: b4: 30; CHECK-NEXT: store i32 [[B:%.*]], ptr [[P]], align 4 31; CHECK-NEXT: br label [[LOOP_BE]] 32; CHECK: loop.be: 33; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 34; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 1000 35; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP_ENTRY]], label [[EXIT:%.*]] 36; CHECK: exit: 37; CHECK-NEXT: ret i32 999 38; 39 40entry: 41 br label %loop.entry 42 43loop.entry: 44 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.be ] 45 %cmp1 = icmp slt i32 %iv, 100 46 br i1 %cmp1, label %b1, label %b2 47 48b1: 49 store i32 %iv, ptr %p 50 br label %merge 51 52b2: 53 store i32 %a, ptr %p 54 br label %merge 55 56merge: 57 %cmp2 = icmp ult i32 %iv, 100 58 br i1 %cmp2, label %b3, label %b4 59 60b3: 61 store i32 %iv, ptr %p 62 br label %loop.be 63 64b4: 65 store i32 %b, ptr %p 66 br label %loop.be 67 68loop.be: 69 %iv.next = add i32 %iv, 1 70 %cmp3 = icmp slt i32 %iv.next, 1000 71 br i1 %cmp3, label %loop.entry, label %exit 72 73exit: 74 ret i32 %iv 75} 76 77define i32 @test_02(i32 %a, i32 %b, ptr %p) { 78; CHECK-LABEL: @test_02( 79; CHECK-NEXT: entry: 80; CHECK-NEXT: br label [[LOOP_ENTRY:%.*]] 81; CHECK: loop.entry: 82; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BE:%.*]] ] 83; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 100, [[IV]] 84; CHECK-NEXT: br i1 [[CMP1]], label [[B1:%.*]], label [[B2:%.*]] 85; CHECK: b1: 86; CHECK-NEXT: store i32 [[IV]], ptr [[P:%.*]], align 4 87; CHECK-NEXT: br label [[MERGE:%.*]] 88; CHECK: b2: 89; CHECK-NEXT: store i32 [[A:%.*]], ptr [[P]], align 4 90; CHECK-NEXT: br label [[MERGE]] 91; CHECK: merge: 92; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 100, [[IV]] 93; CHECK-NEXT: br i1 [[CMP2]], label [[B3:%.*]], label [[B4:%.*]] 94; CHECK: b3: 95; CHECK-NEXT: store i32 [[IV]], ptr [[P]], align 4 96; CHECK-NEXT: br label [[LOOP_BE]] 97; CHECK: b4: 98; CHECK-NEXT: store i32 [[B:%.*]], ptr [[P]], align 4 99; CHECK-NEXT: br label [[LOOP_BE]] 100; CHECK: loop.be: 101; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 102; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 1000 103; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP_ENTRY]], label [[EXIT:%.*]] 104; CHECK: exit: 105; CHECK-NEXT: ret i32 999 106; 107 108entry: 109 br label %loop.entry 110 111loop.entry: 112 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.be ] 113 %cmp1 = icmp sgt i32 100, %iv 114 br i1 %cmp1, label %b1, label %b2 115 116b1: 117 store i32 %iv, ptr %p 118 br label %merge 119 120b2: 121 store i32 %a, ptr %p 122 br label %merge 123 124merge: 125 %cmp2 = icmp ugt i32 100, %iv 126 br i1 %cmp2, label %b3, label %b4 127 128b3: 129 store i32 %iv, ptr %p 130 br label %loop.be 131 132b4: 133 store i32 %b, ptr %p 134 br label %loop.be 135 136loop.be: 137 %iv.next = add i32 %iv, 1 138 %cmp3 = icmp sgt i32 1000, %iv.next 139 br i1 %cmp3, label %loop.entry, label %exit 140 141exit: 142 ret i32 %iv 143} 144 145define i32 @test_03(ptr %p, ptr %capacity_p, ptr %num_elements_p) { 146; CHECK-LABEL: @test_03( 147; CHECK-NEXT: entry: 148; CHECK-NEXT: [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0:![0-9]+]] 149; CHECK-NEXT: [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]] 150; CHECK-NEXT: br label [[LOOP:%.*]] 151; CHECK: loop: 152; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 153; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]] 154; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp slt i32 [[BYTES_TO_WRITE]], 4 155; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]] 156; CHECK: backedge: 157; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]] 158; CHECK-NEXT: store i32 1, ptr [[EL_PTR]], align 4 159; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4 160; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]] 161; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] 162; CHECK: exit: 163; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ] 164; CHECK-NEXT: ret i32 [[IV_NEXT_LCSSA]] 165; CHECK: out_of_bounds: 166; CHECK-NEXT: ret i32 -1 167; 168entry: 169 %capacity = load i32, ptr %capacity_p, !range !0 170 %num_elements = load i32, ptr %num_elements_p, !range !0 171 br label %loop 172 173loop: 174 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 175 %bytes_to_write = sub i32 %capacity, %iv 176 %capacity_check = icmp slt i32 %bytes_to_write, 4 177 br i1 %capacity_check, label %out_of_bounds, label %backedge 178 179backedge: 180 %el.ptr = getelementptr i32, ptr %p, i32 %iv 181 store i32 1, ptr %el.ptr 182 %iv.next = add nuw nsw i32 %iv, 4 183 %loop_cond = icmp slt i32 %iv.next, %num_elements 184 br i1 %loop_cond, label %loop, label %exit 185 186exit: 187 ret i32 %iv.next 188 189out_of_bounds: 190 ret i32 -1 191} 192 193define i32 @test_04(ptr %p, ptr %capacity_p, ptr %num_elements_p) { 194; CHECK-LABEL: @test_04( 195; CHECK-NEXT: entry: 196; CHECK-NEXT: [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0]] 197; CHECK-NEXT: [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]] 198; CHECK-NEXT: br label [[LOOP:%.*]] 199; CHECK: loop: 200; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 201; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]] 202; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp sle i32 [[BYTES_TO_WRITE]], 3 203; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]] 204; CHECK: backedge: 205; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]] 206; CHECK-NEXT: store i32 1, ptr [[EL_PTR]], align 4 207; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4 208; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]] 209; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] 210; CHECK: exit: 211; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ] 212; CHECK-NEXT: ret i32 [[IV_NEXT_LCSSA]] 213; CHECK: out_of_bounds: 214; CHECK-NEXT: ret i32 -1 215; 216entry: 217 %capacity = load i32, ptr %capacity_p, !range !0 218 %num_elements = load i32, ptr %num_elements_p, !range !0 219 br label %loop 220 221loop: 222 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 223 %bytes_to_write = sub i32 %capacity, %iv 224 %capacity_check = icmp sle i32 %bytes_to_write, 3 225 br i1 %capacity_check, label %out_of_bounds, label %backedge 226 227backedge: 228 %el.ptr = getelementptr i32, ptr %p, i32 %iv 229 store i32 1, ptr %el.ptr 230 %iv.next = add nuw nsw i32 %iv, 4 231 %loop_cond = icmp slt i32 %iv.next, %num_elements 232 br i1 %loop_cond, label %loop, label %exit 233 234exit: 235 ret i32 %iv.next 236 237out_of_bounds: 238 ret i32 -1 239} 240 241define i32 @test_05(ptr %p, ptr %capacity_p, ptr %num_elements_p) { 242; CHECK-LABEL: @test_05( 243; CHECK-NEXT: entry: 244; CHECK-NEXT: [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0]] 245; CHECK-NEXT: [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]] 246; CHECK-NEXT: br label [[LOOP:%.*]] 247; CHECK: loop: 248; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 249; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]] 250; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp ult i32 [[BYTES_TO_WRITE]], 4 251; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]] 252; CHECK: backedge: 253; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]] 254; CHECK-NEXT: store i32 1, ptr [[EL_PTR]], align 4 255; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4 256; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]] 257; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] 258; CHECK: exit: 259; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ] 260; CHECK-NEXT: ret i32 [[IV_NEXT_LCSSA]] 261; CHECK: out_of_bounds: 262; CHECK-NEXT: ret i32 -1 263; 264entry: 265 %capacity = load i32, ptr %capacity_p, !range !0 266 %num_elements = load i32, ptr %num_elements_p, !range !0 267 br label %loop 268 269loop: 270 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 271 %bytes_to_write = sub i32 %capacity, %iv 272 %capacity_check = icmp ult i32 %bytes_to_write, 4 273 br i1 %capacity_check, label %out_of_bounds, label %backedge 274 275backedge: 276 %el.ptr = getelementptr i32, ptr %p, i32 %iv 277 store i32 1, ptr %el.ptr 278 %iv.next = add nuw nsw i32 %iv, 4 279 %loop_cond = icmp slt i32 %iv.next, %num_elements 280 br i1 %loop_cond, label %loop, label %exit 281 282exit: 283 ret i32 %iv.next 284 285out_of_bounds: 286 ret i32 -1 287} 288 289define i32 @test_06(ptr %p, ptr %capacity_p, ptr %num_elements_p) { 290; CHECK-LABEL: @test_06( 291; CHECK-NEXT: entry: 292; CHECK-NEXT: [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P:%.*]], align 4, !range [[RNG0]] 293; CHECK-NEXT: [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P:%.*]], align 4, !range [[RNG0]] 294; CHECK-NEXT: br label [[LOOP:%.*]] 295; CHECK: loop: 296; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] 297; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]] 298; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp ule i32 [[BYTES_TO_WRITE]], 3 299; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]] 300; CHECK: backedge: 301; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]] 302; CHECK-NEXT: store i32 1, ptr [[EL_PTR]], align 4 303; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4 304; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]] 305; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] 306; CHECK: exit: 307; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ] 308; CHECK-NEXT: ret i32 [[IV_NEXT_LCSSA]] 309; CHECK: out_of_bounds: 310; CHECK-NEXT: ret i32 -1 311; 312entry: 313 %capacity = load i32, ptr %capacity_p, !range !0 314 %num_elements = load i32, ptr %num_elements_p, !range !0 315 br label %loop 316 317loop: 318 %iv = phi i32 [0, %entry], [%iv.next, %backedge] 319 %bytes_to_write = sub i32 %capacity, %iv 320 %capacity_check = icmp ule i32 %bytes_to_write, 3 321 br i1 %capacity_check, label %out_of_bounds, label %backedge 322 323backedge: 324 %el.ptr = getelementptr i32, ptr %p, i32 %iv 325 store i32 1, ptr %el.ptr 326 %iv.next = add nuw nsw i32 %iv, 4 327 %loop_cond = icmp slt i32 %iv.next, %num_elements 328 br i1 %loop_cond, label %loop, label %exit 329 330exit: 331 ret i32 %iv.next 332 333out_of_bounds: 334 ret i32 -1 335} 336 337!0 = !{i32 1, i32 2147483648} 338