1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 2; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+fp-armv8 -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FP 3; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+soft-float -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT 4 5define void @test_fptosi(i32 %n, ptr %g, ptr %d) { 6; CHECK-FP-LABEL: define void @test_fptosi( 7; CHECK-FP-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0:[0-9]+]] { 8; CHECK-FP-NEXT: entry: 9; CHECK-FP-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 10; CHECK-FP-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 11; CHECK-FP-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] 12; CHECK-FP: while.body.lr.ph: 13; CHECK-FP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 14; CHECK-FP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 15; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) 16; CHECK-FP-NEXT: br label [[WHILE_BODY:%.*]] 17; CHECK-FP: while.body: 18; CHECK-FP-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] 19; CHECK-FP-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP6:%.*]], [[IF_END4]] ] 20; CHECK-FP-NEXT: [[REM:%.*]] = urem i32 [[I_012]], 10 21; CHECK-FP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0 22; CHECK-FP-NEXT: br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]] 23; CHECK-FP: if.then2: 24; CHECK-FP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]] 25; CHECK-FP-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8 26; CHECK-FP-NEXT: [[CONV:%.*]] = fptosi double [[TMP5]] to i32 27; CHECK-FP-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]] 28; CHECK-FP-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4 29; CHECK-FP-NEXT: br label [[IF_END4]] 30; CHECK-FP: if.end4: 31; CHECK-FP-NEXT: [[INC]] = add nuw i32 [[I_012]], 1 32; CHECK-FP-NEXT: [[TMP6]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1) 33; CHECK-FP-NEXT: [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0 34; CHECK-FP-NEXT: br i1 [[TMP7]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]] 35; CHECK-FP: cleanup.loopexit: 36; CHECK-FP-NEXT: br label [[CLEANUP]] 37; CHECK-FP: cleanup: 38; CHECK-FP-NEXT: ret void 39; 40; CHECK-SOFT-LABEL: define void @test_fptosi( 41; CHECK-SOFT-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0:[0-9]+]] { 42; CHECK-SOFT-NEXT: entry: 43; CHECK-SOFT-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 44; CHECK-SOFT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 45; CHECK-SOFT-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] 46; CHECK-SOFT: while.body.lr.ph: 47; CHECK-SOFT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 48; CHECK-SOFT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 49; CHECK-SOFT-NEXT: br label [[WHILE_BODY:%.*]] 50; CHECK-SOFT: while.body: 51; CHECK-SOFT-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] 52; CHECK-SOFT-NEXT: [[REM:%.*]] = urem i32 [[I_012]], 10 53; CHECK-SOFT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0 54; CHECK-SOFT-NEXT: br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]] 55; CHECK-SOFT: if.then2: 56; CHECK-SOFT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]] 57; CHECK-SOFT-NEXT: [[TMP3:%.*]] = load double, ptr [[ARRAYIDX]], align 8 58; CHECK-SOFT-NEXT: [[CONV:%.*]] = fptosi double [[TMP3]] to i32 59; CHECK-SOFT-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]] 60; CHECK-SOFT-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4 61; CHECK-SOFT-NEXT: br label [[IF_END4]] 62; CHECK-SOFT: if.end4: 63; CHECK-SOFT-NEXT: [[INC]] = add nuw i32 [[I_012]], 1 64; CHECK-SOFT-NEXT: [[CMP1:%.*]] = icmp ult i32 [[INC]], [[N]] 65; CHECK-SOFT-NEXT: br i1 [[CMP1]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]] 66; CHECK-SOFT: cleanup.loopexit: 67; CHECK-SOFT-NEXT: br label [[CLEANUP]] 68; CHECK-SOFT: cleanup: 69; CHECK-SOFT-NEXT: ret void 70; 71entry: 72 %n.off = add i32 %n, -1 73 %0 = icmp ult i32 %n.off, 500 74 br i1 %0, label %while.body.lr.ph, label %cleanup 75 76while.body.lr.ph: 77 %1 = load ptr, ptr %d, align 4 78 %2 = load ptr, ptr %g, align 4 79 br label %while.body 80 81while.body: 82 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ] 83 %rem = urem i32 %i.012, 10 84 %tobool = icmp eq i32 %rem, 0 85 br i1 %tobool, label %if.end4, label %if.then2 86 87if.then2: 88 %arrayidx = getelementptr inbounds double, ptr %1, i32 %i.012 89 %3 = load double, ptr %arrayidx, align 8 90 %conv = fptosi double %3 to i32 91 %arrayidx3 = getelementptr inbounds i32, ptr %2, i32 %i.012 92 store i32 %conv, ptr %arrayidx3, align 4 93 br label %if.end4 94 95if.end4: 96 %inc = add nuw i32 %i.012, 1 97 %cmp1 = icmp ult i32 %inc, %n 98 br i1 %cmp1, label %while.body, label %cleanup.loopexit 99 100cleanup.loopexit: 101 br label %cleanup 102 103cleanup: 104 ret void 105} 106 107define void @test_fptoui(i32 %n, ptr %g, ptr %d) { 108; CHECK-FP-LABEL: define void @test_fptoui( 109; CHECK-FP-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0]] { 110; CHECK-FP-NEXT: entry: 111; CHECK-FP-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 112; CHECK-FP-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 113; CHECK-FP-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] 114; CHECK-FP: while.body.lr.ph: 115; CHECK-FP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 116; CHECK-FP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 117; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) 118; CHECK-FP-NEXT: br label [[WHILE_BODY:%.*]] 119; CHECK-FP: while.body: 120; CHECK-FP-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] 121; CHECK-FP-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP6:%.*]], [[IF_END4]] ] 122; CHECK-FP-NEXT: [[REM:%.*]] = urem i32 [[I_012]], 10 123; CHECK-FP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0 124; CHECK-FP-NEXT: br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]] 125; CHECK-FP: if.then2: 126; CHECK-FP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]] 127; CHECK-FP-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8 128; CHECK-FP-NEXT: [[CONV:%.*]] = fptoui double [[TMP5]] to i32 129; CHECK-FP-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]] 130; CHECK-FP-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4 131; CHECK-FP-NEXT: br label [[IF_END4]] 132; CHECK-FP: if.end4: 133; CHECK-FP-NEXT: [[INC]] = add nuw i32 [[I_012]], 1 134; CHECK-FP-NEXT: [[TMP6]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1) 135; CHECK-FP-NEXT: [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0 136; CHECK-FP-NEXT: br i1 [[TMP7]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]] 137; CHECK-FP: cleanup.loopexit: 138; CHECK-FP-NEXT: br label [[CLEANUP]] 139; CHECK-FP: cleanup: 140; CHECK-FP-NEXT: ret void 141; 142; CHECK-SOFT-LABEL: define void @test_fptoui( 143; CHECK-SOFT-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0]] { 144; CHECK-SOFT-NEXT: entry: 145; CHECK-SOFT-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 146; CHECK-SOFT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 147; CHECK-SOFT-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] 148; CHECK-SOFT: while.body.lr.ph: 149; CHECK-SOFT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 150; CHECK-SOFT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 151; CHECK-SOFT-NEXT: br label [[WHILE_BODY:%.*]] 152; CHECK-SOFT: while.body: 153; CHECK-SOFT-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] 154; CHECK-SOFT-NEXT: [[REM:%.*]] = urem i32 [[I_012]], 10 155; CHECK-SOFT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0 156; CHECK-SOFT-NEXT: br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]] 157; CHECK-SOFT: if.then2: 158; CHECK-SOFT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]] 159; CHECK-SOFT-NEXT: [[TMP3:%.*]] = load double, ptr [[ARRAYIDX]], align 8 160; CHECK-SOFT-NEXT: [[CONV:%.*]] = fptoui double [[TMP3]] to i32 161; CHECK-SOFT-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]] 162; CHECK-SOFT-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4 163; CHECK-SOFT-NEXT: br label [[IF_END4]] 164; CHECK-SOFT: if.end4: 165; CHECK-SOFT-NEXT: [[INC]] = add nuw i32 [[I_012]], 1 166; CHECK-SOFT-NEXT: [[CMP1:%.*]] = icmp ult i32 [[INC]], [[N]] 167; CHECK-SOFT-NEXT: br i1 [[CMP1]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]] 168; CHECK-SOFT: cleanup.loopexit: 169; CHECK-SOFT-NEXT: br label [[CLEANUP]] 170; CHECK-SOFT: cleanup: 171; CHECK-SOFT-NEXT: ret void 172; 173entry: 174 %n.off = add i32 %n, -1 175 %0 = icmp ult i32 %n.off, 500 176 br i1 %0, label %while.body.lr.ph, label %cleanup 177 178while.body.lr.ph: 179 %1 = load ptr, ptr %d, align 4 180 %2 = load ptr, ptr %g, align 4 181 br label %while.body 182 183while.body: 184 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ] 185 %rem = urem i32 %i.012, 10 186 %tobool = icmp eq i32 %rem, 0 187 br i1 %tobool, label %if.end4, label %if.then2 188 189if.then2: 190 %arrayidx = getelementptr inbounds double, ptr %1, i32 %i.012 191 %3 = load double, ptr %arrayidx, align 8 192 %conv = fptoui double %3 to i32 193 %arrayidx3 = getelementptr inbounds i32, ptr %2, i32 %i.012 194 store i32 %conv, ptr %arrayidx3, align 4 195 br label %if.end4 196 197if.end4: 198 %inc = add nuw i32 %i.012, 1 199 %cmp1 = icmp ult i32 %inc, %n 200 br i1 %cmp1, label %while.body, label %cleanup.loopexit 201 202cleanup.loopexit: 203 br label %cleanup 204 205cleanup: 206 ret void 207} 208 209define void @load_store_float(i32 %n, ptr %d, ptr %g) { 210; CHECK-LABEL: define void @load_store_float( 211; CHECK-SAME: i32 [[N:%.*]], ptr [[D:%.*]], ptr [[G:%.*]]) #[[ATTR0:[0-9]+]] { 212; CHECK-NEXT: entry: 213; CHECK-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 214; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 215; CHECK-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] 216; CHECK: while.body.lr.ph: 217; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 218; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 219; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) 220; CHECK-NEXT: br label [[WHILE_BODY:%.*]] 221; CHECK: while.body: 222; CHECK-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] 223; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP6:%.*]], [[IF_END4]] ] 224; CHECK-NEXT: [[REM:%.*]] = urem i32 [[I_012]], 10 225; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0 226; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]] 227; CHECK: if.then2: 228; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]] 229; CHECK-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8 230; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 [[I_012]] 231; CHECK-NEXT: store double [[TMP5]], ptr [[ARRAYIDX3]], align 8 232; CHECK-NEXT: br label [[IF_END4]] 233; CHECK: if.end4: 234; CHECK-NEXT: [[INC]] = add nuw i32 [[I_012]], 1 235; CHECK-NEXT: [[TMP6]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1) 236; CHECK-NEXT: [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0 237; CHECK-NEXT: br i1 [[TMP7]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]] 238; CHECK: cleanup.loopexit: 239; CHECK-NEXT: br label [[CLEANUP]] 240; CHECK: cleanup: 241; CHECK-NEXT: ret void 242; 243entry: 244 %n.off = add i32 %n, -1 245 %0 = icmp ult i32 %n.off, 500 246 br i1 %0, label %while.body.lr.ph, label %cleanup 247 248while.body.lr.ph: 249 %1 = load ptr, ptr %d, align 4 250 %2 = load ptr, ptr %g, align 4 251 br label %while.body 252 253while.body: 254 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ] 255 %rem = urem i32 %i.012, 10 256 %tobool = icmp eq i32 %rem, 0 257 br i1 %tobool, label %if.end4, label %if.then2 258 259if.then2: 260 %arrayidx = getelementptr inbounds double, ptr %1, i32 %i.012 261 %3 = load double, ptr %arrayidx, align 8 262 %arrayidx3 = getelementptr inbounds double, ptr %2, i32 %i.012 263 store double %3, ptr %arrayidx3, align 8 264 br label %if.end4 265 266if.end4: 267 %inc = add nuw i32 %i.012, 1 268 %cmp1 = icmp ult i32 %inc, %n 269 br i1 %cmp1, label %while.body, label %cleanup.loopexit 270 271cleanup.loopexit: 272 br label %cleanup 273 274cleanup: 275 ret void 276} 277 278define void @fp_add(i32 %n, ptr %d, ptr %g) { 279; CHECK-FP-LABEL: define void @fp_add( 280; CHECK-FP-SAME: i32 [[N:%.*]], ptr [[D:%.*]], ptr [[G:%.*]]) #[[ATTR0]] { 281; CHECK-FP-NEXT: entry: 282; CHECK-FP-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 283; CHECK-FP-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 284; CHECK-FP-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] 285; CHECK-FP: while.body.lr.ph: 286; CHECK-FP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 287; CHECK-FP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 288; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) 289; CHECK-FP-NEXT: br label [[WHILE_BODY:%.*]] 290; CHECK-FP: while.body: 291; CHECK-FP-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] 292; CHECK-FP-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP7:%.*]], [[IF_END4]] ] 293; CHECK-FP-NEXT: [[REM:%.*]] = urem i32 [[I_012]], 10 294; CHECK-FP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0 295; CHECK-FP-NEXT: br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]] 296; CHECK-FP: if.then2: 297; CHECK-FP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 [[I_012]] 298; CHECK-FP-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX]], align 4 299; CHECK-FP-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i32 [[I_012]] 300; CHECK-FP-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 301; CHECK-FP-NEXT: [[ADD:%.*]] = fadd float [[TMP5]], [[TMP6]] 302; CHECK-FP-NEXT: store float [[ADD]], ptr [[ARRAYIDX3]], align 4 303; CHECK-FP-NEXT: br label [[IF_END4]] 304; CHECK-FP: if.end4: 305; CHECK-FP-NEXT: [[INC]] = add nuw i32 [[I_012]], 1 306; CHECK-FP-NEXT: [[TMP7]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1) 307; CHECK-FP-NEXT: [[TMP8:%.*]] = icmp ne i32 [[TMP7]], 0 308; CHECK-FP-NEXT: br i1 [[TMP8]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]] 309; CHECK-FP: cleanup.loopexit: 310; CHECK-FP-NEXT: br label [[CLEANUP]] 311; CHECK-FP: cleanup: 312; CHECK-FP-NEXT: ret void 313; 314; CHECK-SOFT-LABEL: define void @fp_add( 315; CHECK-SOFT-SAME: i32 [[N:%.*]], ptr [[D:%.*]], ptr [[G:%.*]]) #[[ATTR0]] { 316; CHECK-SOFT-NEXT: entry: 317; CHECK-SOFT-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 318; CHECK-SOFT-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 319; CHECK-SOFT-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] 320; CHECK-SOFT: while.body.lr.ph: 321; CHECK-SOFT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 322; CHECK-SOFT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 323; CHECK-SOFT-NEXT: br label [[WHILE_BODY:%.*]] 324; CHECK-SOFT: while.body: 325; CHECK-SOFT-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] 326; CHECK-SOFT-NEXT: [[REM:%.*]] = urem i32 [[I_012]], 10 327; CHECK-SOFT-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0 328; CHECK-SOFT-NEXT: br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]] 329; CHECK-SOFT: if.then2: 330; CHECK-SOFT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 [[I_012]] 331; CHECK-SOFT-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX]], align 4 332; CHECK-SOFT-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i32 [[I_012]] 333; CHECK-SOFT-NEXT: [[TMP4:%.*]] = load float, ptr [[ARRAYIDX3]], align 4 334; CHECK-SOFT-NEXT: [[ADD:%.*]] = fadd float [[TMP3]], [[TMP4]] 335; CHECK-SOFT-NEXT: store float [[ADD]], ptr [[ARRAYIDX3]], align 4 336; CHECK-SOFT-NEXT: br label [[IF_END4]] 337; CHECK-SOFT: if.end4: 338; CHECK-SOFT-NEXT: [[INC]] = add nuw i32 [[I_012]], 1 339; CHECK-SOFT-NEXT: [[CMP1:%.*]] = icmp ult i32 [[INC]], [[N]] 340; CHECK-SOFT-NEXT: br i1 [[CMP1]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]] 341; CHECK-SOFT: cleanup.loopexit: 342; CHECK-SOFT-NEXT: br label [[CLEANUP]] 343; CHECK-SOFT: cleanup: 344; CHECK-SOFT-NEXT: ret void 345; 346entry: 347 %n.off = add i32 %n, -1 348 %0 = icmp ult i32 %n.off, 500 349 br i1 %0, label %while.body.lr.ph, label %cleanup 350 351while.body.lr.ph: 352 %1 = load ptr, ptr %d, align 4 353 %2 = load ptr, ptr %g, align 4 354 br label %while.body 355 356while.body: 357 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ] 358 %rem = urem i32 %i.012, 10 359 %tobool = icmp eq i32 %rem, 0 360 br i1 %tobool, label %if.end4, label %if.then2 361 362if.then2: 363 %arrayidx = getelementptr inbounds float, ptr %1, i32 %i.012 364 %3 = load float, ptr %arrayidx, align 4 365 %arrayidx3 = getelementptr inbounds float, ptr %2, i32 %i.012 366 %4 = load float, ptr %arrayidx3, align 4 367 %add = fadd float %3, %4 368 store float %add, ptr %arrayidx3, align 4 369 br label %if.end4 370 371if.end4: 372 %inc = add nuw i32 %i.012, 1 373 %cmp1 = icmp ult i32 %inc, %n 374 br i1 %cmp1, label %while.body, label %cleanup.loopexit 375 376cleanup.loopexit: 377 br label %cleanup 378 379cleanup: 380 ret void 381} 382