1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes='indvars' -verify-loop-info -verify-dom-info -verify-scev | FileCheck %s 3 4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" 5 6; Simple case of direct extend of index 7; -------------------------------------- 8 9define void @sext_no_offset(ptr %A, i32 %M) { 10; CHECK-LABEL: @sext_no_offset( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 13; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 14; CHECK-NEXT: br label [[FOR_BODY:%.*]] 15; CHECK: for.body: 16; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 17; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 18; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 19; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 20; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 21; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 22; CHECK: exit: 23; CHECK-NEXT: ret void 24; 25entry: 26 br label %for.body 27 28for.body: 29 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 30 %idxprom.us = sext i32 %j.016.us to i64 31 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 32 tail call void @use_ptr(ptr %arrayidx.us) 33 %inc.us = add nuw nsw i32 %j.016.us, 1 34 %cmp2.us = icmp slt i32 %inc.us, %M 35 br i1 %cmp2.us, label %for.body, label %exit 36 37exit: 38 ret void 39} 40 41define void @zext_no_offset(ptr %A, i32 %M) { 42; CHECK-LABEL: @zext_no_offset( 43; CHECK-NEXT: entry: 44; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 45; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 46; CHECK-NEXT: br label [[FOR_BODY:%.*]] 47; CHECK: for.body: 48; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 49; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 50; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 51; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 52; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 53; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 54; CHECK: exit: 55; CHECK-NEXT: ret void 56; 57entry: 58 br label %for.body 59 60for.body: 61 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 62 %idxprom.us = zext i32 %j.016.us to i64 63 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 64 tail call void @use_ptr(ptr %arrayidx.us) 65 %inc.us = add nuw nsw i32 %j.016.us, 1 66 %cmp2.us = icmp slt i32 %inc.us, %M 67 br i1 %cmp2.us, label %for.body, label %exit 68 69exit: 70 ret void 71} 72 73define void @zext_nneg_no_offset(ptr %A, i32 %M) { 74; CHECK-LABEL: @zext_nneg_no_offset( 75; CHECK-NEXT: entry: 76; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 77; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 78; CHECK-NEXT: br label [[FOR_BODY:%.*]] 79; CHECK: for.body: 80; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 81; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]] 82; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 83; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 84; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 85; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 86; CHECK: exit: 87; CHECK-NEXT: ret void 88; 89entry: 90 br label %for.body 91 92for.body: 93 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 94 %idxprom.us = zext nneg i32 %j.016.us to i64 95 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 96 tail call void @use_ptr(ptr %arrayidx.us) 97 %inc.us = add nuw nsw i32 %j.016.us, 1 98 %cmp2.us = icmp slt i32 %inc.us, %M 99 br i1 %cmp2.us, label %for.body, label %exit 100 101exit: 102 ret void 103} 104 105; Offset with a loop invariant value, various combinations 106; -------------------------------------- 107 108define void @sext_add_nsw(ptr %A, i32 %offset, i32 %M) { 109; CHECK-LABEL: @sext_add_nsw( 110; CHECK-NEXT: entry: 111; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[OFFSET:%.*]] to i64 112; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 113; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 114; CHECK-NEXT: br label [[FOR_BODY:%.*]] 115; CHECK: for.body: 116; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 117; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], [[TMP0]] 118; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 119; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 120; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 121; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 122; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 123; CHECK: exit: 124; CHECK-NEXT: ret void 125; 126entry: 127 br label %for.body 128 129for.body: 130 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 131 %add.us = add nsw i32 %j.016.us, %offset 132 %idxprom.us = sext i32 %add.us to i64 133 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 134 tail call void @use_ptr(ptr %arrayidx.us) 135 %inc.us = add nuw nsw i32 %j.016.us, 1 136 %cmp2.us = icmp slt i32 %inc.us, %M 137 br i1 %cmp2.us, label %for.body, label %exit 138 139exit: 140 ret void 141} 142 143define void @sext_add_nuw(ptr %A, i32 %offset, i32 %M) { 144; CHECK-LABEL: @sext_add_nuw( 145; CHECK-NEXT: entry: 146; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64 147; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 148; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 149; CHECK-NEXT: br label [[FOR_BODY:%.*]] 150; CHECK: for.body: 151; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 152; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]] 153; CHECK-NEXT: [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32 154; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[TMP2]] to i64 155; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 156; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 157; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 158; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 159; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 160; CHECK: exit: 161; CHECK-NEXT: ret void 162; 163entry: 164 br label %for.body 165 166for.body: 167 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 168 %add.us = add nuw i32 %j.016.us, %offset 169 %idxprom.us = sext i32 %add.us to i64 170 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 171 tail call void @use_ptr(ptr %arrayidx.us) 172 %inc.us = add nuw nsw i32 %j.016.us, 1 173 %cmp2.us = icmp slt i32 %inc.us, %M 174 br i1 %cmp2.us, label %for.body, label %exit 175 176exit: 177 ret void 178} 179 180define void @sext_add_noflags(ptr %A, i32 %offset, i32 %M) { 181; CHECK-LABEL: @sext_add_noflags( 182; CHECK-NEXT: entry: 183; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 184; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 185; CHECK-NEXT: br label [[FOR_BODY:%.*]] 186; CHECK: for.body: 187; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 188; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32 189; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]] 190; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64 191; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 192; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 193; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 194; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 195; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 196; CHECK: exit: 197; CHECK-NEXT: ret void 198; 199entry: 200 br label %for.body 201 202for.body: 203 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 204 %add.us = add i32 %j.016.us, %offset 205 %idxprom.us = sext i32 %add.us to i64 206 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 207 tail call void @use_ptr(ptr %arrayidx.us) 208 %inc.us = add nuw nsw i32 %j.016.us, 1 209 %cmp2.us = icmp slt i32 %inc.us, %M 210 br i1 %cmp2.us, label %for.body, label %exit 211 212exit: 213 ret void 214} 215 216define void @zext_add_nsw(ptr %A, i32 %offset, i32 %M) { 217; CHECK-LABEL: @zext_add_nsw( 218; CHECK-NEXT: entry: 219; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[OFFSET:%.*]] to i64 220; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 221; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 222; CHECK-NEXT: br label [[FOR_BODY:%.*]] 223; CHECK: for.body: 224; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 225; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], [[TMP0]] 226; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[TMP1]] to i32 227; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[TMP2]] to i64 228; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 229; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 230; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 231; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 232; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 233; CHECK: exit: 234; CHECK-NEXT: ret void 235; 236entry: 237 br label %for.body 238 239for.body: 240 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 241 %add.us = add nsw i32 %j.016.us, %offset 242 %idxprom.us = zext i32 %add.us to i64 243 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 244 tail call void @use_ptr(ptr %arrayidx.us) 245 %inc.us = add nuw nsw i32 %j.016.us, 1 246 %cmp2.us = icmp slt i32 %inc.us, %M 247 br i1 %cmp2.us, label %for.body, label %exit 248 249exit: 250 ret void 251} 252 253define void @zext_add_nuw(ptr %A, i32 %offset, i32 %M) { 254; CHECK-LABEL: @zext_add_nuw( 255; CHECK-NEXT: entry: 256; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64 257; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 258; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 259; CHECK-NEXT: br label [[FOR_BODY:%.*]] 260; CHECK: for.body: 261; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 262; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]] 263; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 264; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 265; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 266; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 267; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 268; CHECK: exit: 269; CHECK-NEXT: ret void 270; 271entry: 272 br label %for.body 273 274for.body: 275 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 276 %add.us = add nuw i32 %j.016.us, %offset 277 %idxprom.us = zext i32 %add.us to i64 278 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 279 tail call void @use_ptr(ptr %arrayidx.us) 280 %inc.us = add nuw nsw i32 %j.016.us, 1 281 %cmp2.us = icmp slt i32 %inc.us, %M 282 br i1 %cmp2.us, label %for.body, label %exit 283 284exit: 285 ret void 286} 287 288define void @zext_add_noflags(ptr %A, i32 %offset, i32 %M) { 289; CHECK-LABEL: @zext_add_noflags( 290; CHECK-NEXT: entry: 291; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 292; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 293; CHECK-NEXT: br label [[FOR_BODY:%.*]] 294; CHECK: for.body: 295; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 296; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32 297; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]] 298; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64 299; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 300; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 301; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 302; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 303; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 304; CHECK: exit: 305; CHECK-NEXT: ret void 306; 307entry: 308 br label %for.body 309 310for.body: 311 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 312 %add.us = add i32 %j.016.us, %offset 313 %idxprom.us = zext i32 %add.us to i64 314 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 315 tail call void @use_ptr(ptr %arrayidx.us) 316 %inc.us = add nuw nsw i32 %j.016.us, 1 317 %cmp2.us = icmp slt i32 %inc.us, %M 318 br i1 %cmp2.us, label %for.body, label %exit 319 320exit: 321 ret void 322} 323 324define void @zext_nneg_add_nsw(ptr %A, i32 %offset, i32 %M) { 325; CHECK-LABEL: @zext_nneg_add_nsw( 326; CHECK-NEXT: entry: 327; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[OFFSET:%.*]] to i64 328; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 329; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 330; CHECK-NEXT: br label [[FOR_BODY:%.*]] 331; CHECK: for.body: 332; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 333; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], [[TMP0]] 334; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 335; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 336; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 337; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 338; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 339; CHECK: exit: 340; CHECK-NEXT: ret void 341; 342entry: 343 br label %for.body 344 345for.body: 346 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 347 %add.us = add nsw i32 %j.016.us, %offset 348 %idxprom.us = zext nneg i32 %add.us to i64 349 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 350 tail call void @use_ptr(ptr %arrayidx.us) 351 %inc.us = add nuw nsw i32 %j.016.us, 1 352 %cmp2.us = icmp slt i32 %inc.us, %M 353 br i1 %cmp2.us, label %for.body, label %exit 354 355exit: 356 ret void 357} 358 359define void @zext_nneg_add_nuw(ptr %A, i32 %offset, i32 %M) { 360; CHECK-LABEL: @zext_nneg_add_nuw( 361; CHECK-NEXT: entry: 362; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64 363; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 364; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 365; CHECK-NEXT: br label [[FOR_BODY:%.*]] 366; CHECK: for.body: 367; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 368; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]] 369; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 370; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 371; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 372; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 373; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 374; CHECK: exit: 375; CHECK-NEXT: ret void 376; 377entry: 378 br label %for.body 379 380for.body: 381 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 382 %add.us = add nuw i32 %j.016.us, %offset 383 %idxprom.us = zext nneg i32 %add.us to i64 384 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 385 tail call void @use_ptr(ptr %arrayidx.us) 386 %inc.us = add nuw nsw i32 %j.016.us, 1 387 %cmp2.us = icmp slt i32 %inc.us, %M 388 br i1 %cmp2.us, label %for.body, label %exit 389 390exit: 391 ret void 392} 393 394define void @zext_nneg_add_noflags(ptr %A, i32 %offset, i32 %M) { 395; CHECK-LABEL: @zext_nneg_add_noflags( 396; CHECK-NEXT: entry: 397; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 398; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 399; CHECK-NEXT: br label [[FOR_BODY:%.*]] 400; CHECK: for.body: 401; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 402; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32 403; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]] 404; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext nneg i32 [[ADD_US]] to i64 405; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 406; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 407; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 408; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 409; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 410; CHECK: exit: 411; CHECK-NEXT: ret void 412; 413entry: 414 br label %for.body 415 416for.body: 417 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 418 %add.us = add i32 %j.016.us, %offset 419 %idxprom.us = zext nneg i32 %add.us to i64 420 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 421 tail call void @use_ptr(ptr %arrayidx.us) 422 %inc.us = add nuw nsw i32 %j.016.us, 1 423 %cmp2.us = icmp slt i32 %inc.us, %M 424 br i1 %cmp2.us, label %for.body, label %exit 425 426exit: 427 ret void 428} 429 430; Offset is multiplied by a multiple 431; -------------------------------------- 432 433define void @sext_mul_nsw(ptr %A, i32 %multiple, i32 %M) { 434; CHECK-LABEL: @sext_mul_nsw( 435; CHECK-NEXT: entry: 436; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[MULTIPLE:%.*]] to i64 437; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 438; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 439; CHECK-NEXT: br label [[FOR_BODY:%.*]] 440; CHECK: for.body: 441; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 442; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i64 [[INDVARS_IV]], [[TMP0]] 443; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 444; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 445; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 446; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 447; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 448; CHECK: exit: 449; CHECK-NEXT: ret void 450; 451entry: 452 br label %for.body 453 454for.body: 455 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 456 %mul.us = mul nsw i32 %j.016.us, %multiple 457 %idxprom.us = sext i32 %mul.us to i64 458 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 459 tail call void @use_ptr(ptr %arrayidx.us) 460 %inc.us = add nuw nsw i32 %j.016.us, 1 461 %cmp2.us = icmp slt i32 %inc.us, %M 462 br i1 %cmp2.us, label %for.body, label %exit 463 464exit: 465 ret void 466} 467 468define void @sext_mul_nuw(ptr %A, i32 %multiple, i32 %M) { 469; CHECK-LABEL: @sext_mul_nuw( 470; CHECK-NEXT: entry: 471; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64 472; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 473; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 474; CHECK-NEXT: br label [[FOR_BODY:%.*]] 475; CHECK: for.body: 476; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 477; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]] 478; CHECK-NEXT: [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32 479; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[TMP2]] to i64 480; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 481; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 482; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 483; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 484; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 485; CHECK: exit: 486; CHECK-NEXT: ret void 487; 488entry: 489 br label %for.body 490 491for.body: 492 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 493 %mul.us = mul nuw i32 %j.016.us, %multiple 494 %idxprom.us = sext i32 %mul.us to i64 495 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 496 tail call void @use_ptr(ptr %arrayidx.us) 497 %inc.us = add nuw nsw i32 %j.016.us, 1 498 %cmp2.us = icmp slt i32 %inc.us, %M 499 br i1 %cmp2.us, label %for.body, label %exit 500 501exit: 502 ret void 503} 504 505define void @sext_mul_noflags(ptr %A, i32 %multiple, i32 %M) { 506; CHECK-LABEL: @sext_mul_noflags( 507; CHECK-NEXT: entry: 508; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 509; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 510; CHECK-NEXT: br label [[FOR_BODY:%.*]] 511; CHECK: for.body: 512; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 513; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32 514; CHECK-NEXT: [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]] 515; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[MUL_US]] to i64 516; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 517; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 518; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 519; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 520; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 521; CHECK: exit: 522; CHECK-NEXT: ret void 523; 524entry: 525 br label %for.body 526 527for.body: 528 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 529 %mul.us = mul i32 %j.016.us, %multiple 530 %idxprom.us = sext i32 %mul.us to i64 531 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 532 tail call void @use_ptr(ptr %arrayidx.us) 533 %inc.us = add nuw nsw i32 %j.016.us, 1 534 %cmp2.us = icmp slt i32 %inc.us, %M 535 br i1 %cmp2.us, label %for.body, label %exit 536 537exit: 538 ret void 539} 540 541define void @zext_mul_nsw(ptr %A, i32 %multiple, i32 %M) { 542; CHECK-LABEL: @zext_mul_nsw( 543; CHECK-NEXT: entry: 544; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[MULTIPLE:%.*]] to i64 545; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 546; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 547; CHECK-NEXT: br label [[FOR_BODY:%.*]] 548; CHECK: for.body: 549; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 550; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i64 [[INDVARS_IV]], [[TMP0]] 551; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[TMP1]] to i32 552; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[TMP2]] to i64 553; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 554; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 555; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 556; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 557; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 558; CHECK: exit: 559; CHECK-NEXT: ret void 560; 561entry: 562 br label %for.body 563 564for.body: 565 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 566 %mul.us = mul nsw i32 %j.016.us, %multiple 567 %idxprom.us = zext i32 %mul.us to i64 568 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 569 tail call void @use_ptr(ptr %arrayidx.us) 570 %inc.us = add nuw nsw i32 %j.016.us, 1 571 %cmp2.us = icmp slt i32 %inc.us, %M 572 br i1 %cmp2.us, label %for.body, label %exit 573 574exit: 575 ret void 576} 577 578define void @zext_mul_nuw(ptr %A, i32 %multiple, i32 %M) { 579; CHECK-LABEL: @zext_mul_nuw( 580; CHECK-NEXT: entry: 581; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64 582; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 583; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 584; CHECK-NEXT: br label [[FOR_BODY:%.*]] 585; CHECK: for.body: 586; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 587; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]] 588; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 589; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 590; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 591; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 592; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 593; CHECK: exit: 594; CHECK-NEXT: ret void 595; 596entry: 597 br label %for.body 598 599for.body: 600 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 601 %mul.us = mul nuw i32 %j.016.us, %multiple 602 %idxprom.us = zext i32 %mul.us to i64 603 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 604 tail call void @use_ptr(ptr %arrayidx.us) 605 %inc.us = add nuw nsw i32 %j.016.us, 1 606 %cmp2.us = icmp slt i32 %inc.us, %M 607 br i1 %cmp2.us, label %for.body, label %exit 608 609exit: 610 ret void 611} 612 613define void @zext_mul_noflags(ptr %A, i32 %multiple, i32 %M) { 614; CHECK-LABEL: @zext_mul_noflags( 615; CHECK-NEXT: entry: 616; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 617; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 618; CHECK-NEXT: br label [[FOR_BODY:%.*]] 619; CHECK: for.body: 620; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 621; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32 622; CHECK-NEXT: [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]] 623; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[MUL_US]] to i64 624; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 625; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 626; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 627; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 628; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 629; CHECK: exit: 630; CHECK-NEXT: ret void 631; 632entry: 633 br label %for.body 634 635for.body: 636 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 637 %mul.us = mul i32 %j.016.us, %multiple 638 %idxprom.us = zext i32 %mul.us to i64 639 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 640 tail call void @use_ptr(ptr %arrayidx.us) 641 %inc.us = add nuw nsw i32 %j.016.us, 1 642 %cmp2.us = icmp slt i32 %inc.us, %M 643 br i1 %cmp2.us, label %for.body, label %exit 644 645exit: 646 ret void 647} 648 649define void @zext_nneg_mul_nsw(ptr %A, i32 %multiple, i32 %M) { 650; CHECK-LABEL: @zext_nneg_mul_nsw( 651; CHECK-NEXT: entry: 652; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[MULTIPLE:%.*]] to i64 653; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 654; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 655; CHECK-NEXT: br label [[FOR_BODY:%.*]] 656; CHECK: for.body: 657; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 658; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i64 [[INDVARS_IV]], [[TMP0]] 659; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 660; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 661; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 662; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 663; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 664; CHECK: exit: 665; CHECK-NEXT: ret void 666; 667entry: 668 br label %for.body 669 670for.body: 671 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 672 %mul.us = mul nsw i32 %j.016.us, %multiple 673 %idxprom.us = zext nneg i32 %mul.us to i64 674 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 675 tail call void @use_ptr(ptr %arrayidx.us) 676 %inc.us = add nuw nsw i32 %j.016.us, 1 677 %cmp2.us = icmp slt i32 %inc.us, %M 678 br i1 %cmp2.us, label %for.body, label %exit 679 680exit: 681 ret void 682} 683 684define void @zext_nneg_mul_nuw(ptr %A, i32 %multiple, i32 %M) { 685; CHECK-LABEL: @zext_nneg_mul_nuw( 686; CHECK-NEXT: entry: 687; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64 688; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 689; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 690; CHECK-NEXT: br label [[FOR_BODY:%.*]] 691; CHECK: for.body: 692; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 693; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]] 694; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]] 695; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 696; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 697; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 698; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 699; CHECK: exit: 700; CHECK-NEXT: ret void 701; 702entry: 703 br label %for.body 704 705for.body: 706 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 707 %mul.us = mul nuw i32 %j.016.us, %multiple 708 %idxprom.us = zext nneg i32 %mul.us to i64 709 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 710 tail call void @use_ptr(ptr %arrayidx.us) 711 %inc.us = add nuw nsw i32 %j.016.us, 1 712 %cmp2.us = icmp slt i32 %inc.us, %M 713 br i1 %cmp2.us, label %for.body, label %exit 714 715exit: 716 ret void 717} 718 719define void @zext_nneg_mul_noflags(ptr %A, i32 %multiple, i32 %M) { 720; CHECK-LABEL: @zext_nneg_mul_noflags( 721; CHECK-NEXT: entry: 722; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1) 723; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64 724; CHECK-NEXT: br label [[FOR_BODY:%.*]] 725; CHECK: for.body: 726; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ] 727; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32 728; CHECK-NEXT: [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]] 729; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext nneg i32 [[MUL_US]] to i64 730; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] 731; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]]) 732; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 733; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 734; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]] 735; CHECK: exit: 736; CHECK-NEXT: ret void 737; 738entry: 739 br label %for.body 740 741for.body: 742 %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ] 743 %mul.us = mul i32 %j.016.us, %multiple 744 %idxprom.us = zext nneg i32 %mul.us to i64 745 %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us 746 tail call void @use_ptr(ptr %arrayidx.us) 747 %inc.us = add nuw nsw i32 %j.016.us, 1 748 %cmp2.us = icmp slt i32 %inc.us, %M 749 br i1 %cmp2.us, label %for.body, label %exit 750 751exit: 752 ret void 753} 754 755declare dso_local void @use_ptr(ptr %0) 756