1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -O3 -mtriple=arm-arm-eabi -mcpu=cortex-m33 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-LE 3; RUN: llc -O3 -mtriple=armeb-arm-eabi -mcpu=cortex-m33 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-BE 4 5define i32 @add_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 6; CHECK-LE-LABEL: add_user: 7; CHECK-LE: @ %bb.0: @ %entry 8; CHECK-LE-NEXT: .save {r4, lr} 9; CHECK-LE-NEXT: push {r4, lr} 10; CHECK-LE-NEXT: cmp r0, #1 11; CHECK-LE-NEXT: blt .LBB0_4 12; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader 13; CHECK-LE-NEXT: subs r2, #2 14; CHECK-LE-NEXT: subs r3, #2 15; CHECK-LE-NEXT: mov.w r12, #0 16; CHECK-LE-NEXT: movs r1, #0 17; CHECK-LE-NEXT: .p2align 2 18; CHECK-LE-NEXT: .LBB0_2: @ %for.body 19; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1 20; CHECK-LE-NEXT: ldr lr, [r3, #2]! 21; CHECK-LE-NEXT: ldr r4, [r2, #2]! 22; CHECK-LE-NEXT: subs r0, #1 23; CHECK-LE-NEXT: smlad r12, r4, lr, r12 24; CHECK-LE-NEXT: sxtah r1, r1, lr 25; CHECK-LE-NEXT: bne .LBB0_2 26; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup 27; CHECK-LE-NEXT: add.w r0, r12, r1 28; CHECK-LE-NEXT: pop {r4, pc} 29; CHECK-LE-NEXT: .LBB0_4: 30; CHECK-LE-NEXT: mov.w r12, #0 31; CHECK-LE-NEXT: movs r1, #0 32; CHECK-LE-NEXT: add.w r0, r12, r1 33; CHECK-LE-NEXT: pop {r4, pc} 34; 35; CHECK-BE-LABEL: add_user: 36; CHECK-BE: @ %bb.0: @ %entry 37; CHECK-BE-NEXT: .save {r4, r5, r6, lr} 38; CHECK-BE-NEXT: push {r4, r5, r6, lr} 39; CHECK-BE-NEXT: cmp r0, #1 40; CHECK-BE-NEXT: blt .LBB0_4 41; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader 42; CHECK-BE-NEXT: subs r2, #2 43; CHECK-BE-NEXT: subs r3, #2 44; CHECK-BE-NEXT: mov.w r12, #0 45; CHECK-BE-NEXT: movs r1, #0 46; CHECK-BE-NEXT: .p2align 2 47; CHECK-BE-NEXT: .LBB0_2: @ %for.body 48; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1 49; CHECK-BE-NEXT: ldrsh lr, [r3, #2]! 50; CHECK-BE-NEXT: ldrsh r5, [r2, #2]! 51; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2] 52; CHECK-BE-NEXT: ldrsh.w r6, [r2, #2] 53; CHECK-BE-NEXT: smlabb r5, r5, lr, r12 54; CHECK-BE-NEXT: add r1, lr 55; CHECK-BE-NEXT: subs r0, #1 56; CHECK-BE-NEXT: smlabb r12, r6, r4, r5 57; CHECK-BE-NEXT: bne .LBB0_2 58; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup 59; CHECK-BE-NEXT: add.w r0, r12, r1 60; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 61; CHECK-BE-NEXT: .LBB0_4: 62; CHECK-BE-NEXT: mov.w r12, #0 63; CHECK-BE-NEXT: movs r1, #0 64; CHECK-BE-NEXT: add.w r0, r12, r1 65; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 66entry: 67 %cmp24 = icmp sgt i32 %arg, 0 68 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 69 70for.body.preheader: 71 %.pre = load i16, i16* %arg3, align 2 72 %.pre27 = load i16, i16* %arg2, align 2 73 br label %for.body 74 75for.cond.cleanup: 76 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 77 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ] 78 %res = add i32 %mac1.0.lcssa, %count.final 79 ret i32 %res 80 81for.body: 82 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 83 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 84 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ] 85 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 86 %0 = load i16, i16* %arrayidx, align 2 87 %add = add nuw nsw i32 %i.025, 1 88 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 89 %1 = load i16, i16* %arrayidx1, align 2 90 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 91 %2 = load i16, i16* %arrayidx3, align 2 92 %conv = sext i16 %2 to i32 93 %conv4 = sext i16 %0 to i32 94 %count.next = add i32 %conv4, %count 95 %mul = mul nsw i32 %conv, %conv4 96 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 97 %3 = load i16, i16* %arrayidx6, align 2 98 %conv7 = sext i16 %3 to i32 99 %conv8 = sext i16 %1 to i32 100 %mul9 = mul nsw i32 %conv7, %conv8 101 %add10 = add i32 %mul, %mac1.026 102 %add11 = add i32 %mul9, %add10 103 %exitcond = icmp ne i32 %add, %arg 104 br i1 %exitcond, label %for.body, label %for.cond.cleanup 105} 106 107define i32 @mul_bottom_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 108; CHECK-LE-LABEL: mul_bottom_user: 109; CHECK-LE: @ %bb.0: @ %entry 110; CHECK-LE-NEXT: .save {r4, r5, r7, lr} 111; CHECK-LE-NEXT: push {r4, r5, r7, lr} 112; CHECK-LE-NEXT: cmp r0, #1 113; CHECK-LE-NEXT: blt .LBB1_4 114; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader 115; CHECK-LE-NEXT: sub.w lr, r2, #2 116; CHECK-LE-NEXT: subs r3, #2 117; CHECK-LE-NEXT: mov.w r12, #0 118; CHECK-LE-NEXT: movs r1, #0 119; CHECK-LE-NEXT: .p2align 2 120; CHECK-LE-NEXT: .LBB1_2: @ %for.body 121; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1 122; CHECK-LE-NEXT: ldr r2, [r3, #2]! 123; CHECK-LE-NEXT: ldr r4, [lr, #2]! 124; CHECK-LE-NEXT: sxth r5, r2 125; CHECK-LE-NEXT: smlad r12, r4, r2, r12 126; CHECK-LE-NEXT: subs r0, #1 127; CHECK-LE-NEXT: mul r1, r5, r1 128; CHECK-LE-NEXT: bne .LBB1_2 129; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup 130; CHECK-LE-NEXT: add.w r0, r12, r1 131; CHECK-LE-NEXT: pop {r4, r5, r7, pc} 132; CHECK-LE-NEXT: .LBB1_4: 133; CHECK-LE-NEXT: mov.w r12, #0 134; CHECK-LE-NEXT: movs r1, #0 135; CHECK-LE-NEXT: add.w r0, r12, r1 136; CHECK-LE-NEXT: pop {r4, r5, r7, pc} 137; 138; CHECK-BE-LABEL: mul_bottom_user: 139; CHECK-BE: @ %bb.0: @ %entry 140; CHECK-BE-NEXT: .save {r4, r5, r6, lr} 141; CHECK-BE-NEXT: push {r4, r5, r6, lr} 142; CHECK-BE-NEXT: cmp r0, #1 143; CHECK-BE-NEXT: blt .LBB1_4 144; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader 145; CHECK-BE-NEXT: subs r2, #2 146; CHECK-BE-NEXT: subs r3, #2 147; CHECK-BE-NEXT: mov.w r12, #0 148; CHECK-BE-NEXT: movs r1, #0 149; CHECK-BE-NEXT: .p2align 2 150; CHECK-BE-NEXT: .LBB1_2: @ %for.body 151; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1 152; CHECK-BE-NEXT: ldrsh lr, [r3, #2]! 153; CHECK-BE-NEXT: ldrsh r4, [r2, #2]! 154; CHECK-BE-NEXT: ldrsh.w r5, [r3, #2] 155; CHECK-BE-NEXT: ldrsh.w r6, [r2, #2] 156; CHECK-BE-NEXT: smlabb r4, r4, lr, r12 157; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 158; CHECK-BE-NEXT: subs r0, #1 159; CHECK-BE-NEXT: mul r1, lr, r1 160; CHECK-BE-NEXT: bne .LBB1_2 161; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup 162; CHECK-BE-NEXT: add.w r0, r12, r1 163; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 164; CHECK-BE-NEXT: .LBB1_4: 165; CHECK-BE-NEXT: mov.w r12, #0 166; CHECK-BE-NEXT: movs r1, #0 167; CHECK-BE-NEXT: add.w r0, r12, r1 168; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 169entry: 170 %cmp24 = icmp sgt i32 %arg, 0 171 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 172 173for.body.preheader: 174 %.pre = load i16, i16* %arg3, align 2 175 %.pre27 = load i16, i16* %arg2, align 2 176 br label %for.body 177 178for.cond.cleanup: 179 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 180 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ] 181 %res = add i32 %mac1.0.lcssa, %count.final 182 ret i32 %res 183 184for.body: 185 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 186 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 187 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ] 188 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 189 %0 = load i16, i16* %arrayidx, align 2 190 %add = add nuw nsw i32 %i.025, 1 191 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 192 %1 = load i16, i16* %arrayidx1, align 2 193 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 194 %2 = load i16, i16* %arrayidx3, align 2 195 %conv = sext i16 %2 to i32 196 %conv4 = sext i16 %0 to i32 197 %mul = mul nsw i32 %conv, %conv4 198 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 199 %3 = load i16, i16* %arrayidx6, align 2 200 %conv7 = sext i16 %3 to i32 201 %conv8 = sext i16 %1 to i32 202 %mul9 = mul nsw i32 %conv7, %conv8 203 %add10 = add i32 %mul, %mac1.026 204 %add11 = add i32 %mul9, %add10 205 %count.next = mul i32 %conv4, %count 206 %exitcond = icmp ne i32 %add, %arg 207 br i1 %exitcond, label %for.body, label %for.cond.cleanup 208} 209 210define i32 @mul_top_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 211; CHECK-LE-LABEL: mul_top_user: 212; CHECK-LE: @ %bb.0: @ %entry 213; CHECK-LE-NEXT: .save {r4, lr} 214; CHECK-LE-NEXT: push {r4, lr} 215; CHECK-LE-NEXT: cmp r0, #1 216; CHECK-LE-NEXT: blt .LBB2_4 217; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader 218; CHECK-LE-NEXT: subs r2, #2 219; CHECK-LE-NEXT: subs r3, #2 220; CHECK-LE-NEXT: mov.w r12, #0 221; CHECK-LE-NEXT: movs r1, #0 222; CHECK-LE-NEXT: .p2align 2 223; CHECK-LE-NEXT: .LBB2_2: @ %for.body 224; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1 225; CHECK-LE-NEXT: ldr lr, [r3, #2]! 226; CHECK-LE-NEXT: ldr r4, [r2, #2]! 227; CHECK-LE-NEXT: subs r0, #1 228; CHECK-LE-NEXT: smlad r12, r4, lr, r12 229; CHECK-LE-NEXT: asr.w r4, r4, #16 230; CHECK-LE-NEXT: mul r1, r4, r1 231; CHECK-LE-NEXT: bne .LBB2_2 232; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup 233; CHECK-LE-NEXT: add.w r0, r12, r1 234; CHECK-LE-NEXT: pop {r4, pc} 235; CHECK-LE-NEXT: .LBB2_4: 236; CHECK-LE-NEXT: mov.w r12, #0 237; CHECK-LE-NEXT: movs r1, #0 238; CHECK-LE-NEXT: add.w r0, r12, r1 239; CHECK-LE-NEXT: pop {r4, pc} 240; 241; CHECK-BE-LABEL: mul_top_user: 242; CHECK-BE: @ %bb.0: @ %entry 243; CHECK-BE-NEXT: .save {r4, r5, r6, lr} 244; CHECK-BE-NEXT: push {r4, r5, r6, lr} 245; CHECK-BE-NEXT: cmp r0, #1 246; CHECK-BE-NEXT: blt .LBB2_4 247; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader 248; CHECK-BE-NEXT: subs r2, #2 249; CHECK-BE-NEXT: subs r3, #2 250; CHECK-BE-NEXT: mov.w r12, #0 251; CHECK-BE-NEXT: movs r1, #0 252; CHECK-BE-NEXT: .p2align 2 253; CHECK-BE-NEXT: .LBB2_2: @ %for.body 254; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1 255; CHECK-BE-NEXT: ldrsh lr, [r3, #2]! 256; CHECK-BE-NEXT: ldrsh r4, [r2, #2]! 257; CHECK-BE-NEXT: ldrsh.w r5, [r3, #2] 258; CHECK-BE-NEXT: ldrsh.w r6, [r2, #2] 259; CHECK-BE-NEXT: smlabb r4, r4, lr, r12 260; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 261; CHECK-BE-NEXT: subs r0, #1 262; CHECK-BE-NEXT: mul r1, r6, r1 263; CHECK-BE-NEXT: bne .LBB2_2 264; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup 265; CHECK-BE-NEXT: add.w r0, r12, r1 266; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 267; CHECK-BE-NEXT: .LBB2_4: 268; CHECK-BE-NEXT: mov.w r12, #0 269; CHECK-BE-NEXT: movs r1, #0 270; CHECK-BE-NEXT: add.w r0, r12, r1 271; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 272entry: 273 %cmp24 = icmp sgt i32 %arg, 0 274 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 275 276for.body.preheader: 277 %.pre = load i16, i16* %arg3, align 2 278 %.pre27 = load i16, i16* %arg2, align 2 279 br label %for.body 280 281for.cond.cleanup: 282 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 283 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ] 284 %res = add i32 %mac1.0.lcssa, %count.final 285 ret i32 %res 286 287for.body: 288 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 289 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 290 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ] 291 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 292 %0 = load i16, i16* %arrayidx, align 2 293 %add = add nuw nsw i32 %i.025, 1 294 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 295 %1 = load i16, i16* %arrayidx1, align 2 296 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 297 %2 = load i16, i16* %arrayidx3, align 2 298 %conv = sext i16 %2 to i32 299 %conv4 = sext i16 %0 to i32 300 %mul = mul nsw i32 %conv, %conv4 301 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 302 %3 = load i16, i16* %arrayidx6, align 2 303 %conv7 = sext i16 %3 to i32 304 %conv8 = sext i16 %1 to i32 305 %mul9 = mul nsw i32 %conv7, %conv8 306 %add10 = add i32 %mul, %mac1.026 307 %add11 = add i32 %mul9, %add10 308 %count.next = mul i32 %conv7, %count 309 %exitcond = icmp ne i32 %add, %arg 310 br i1 %exitcond, label %for.body, label %for.cond.cleanup 311} 312 313define i32 @and_user(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 314; CHECK-LE-LABEL: and_user: 315; CHECK-LE: @ %bb.0: @ %entry 316; CHECK-LE-NEXT: .save {r4, lr} 317; CHECK-LE-NEXT: push {r4, lr} 318; CHECK-LE-NEXT: cmp r0, #1 319; CHECK-LE-NEXT: blt .LBB3_4 320; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader 321; CHECK-LE-NEXT: sub.w lr, r2, #2 322; CHECK-LE-NEXT: subs r3, #2 323; CHECK-LE-NEXT: mov.w r12, #0 324; CHECK-LE-NEXT: movs r1, #0 325; CHECK-LE-NEXT: .p2align 2 326; CHECK-LE-NEXT: .LBB3_2: @ %for.body 327; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1 328; CHECK-LE-NEXT: ldr r2, [r3, #2]! 329; CHECK-LE-NEXT: ldr r4, [lr, #2]! 330; CHECK-LE-NEXT: subs r0, #1 331; CHECK-LE-NEXT: smlad r12, r4, r2, r12 332; CHECK-LE-NEXT: uxth r2, r2 333; CHECK-LE-NEXT: mul r1, r2, r1 334; CHECK-LE-NEXT: bne .LBB3_2 335; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup 336; CHECK-LE-NEXT: add.w r0, r12, r1 337; CHECK-LE-NEXT: pop {r4, pc} 338; CHECK-LE-NEXT: .LBB3_4: 339; CHECK-LE-NEXT: mov.w r12, #0 340; CHECK-LE-NEXT: movs r1, #0 341; CHECK-LE-NEXT: add.w r0, r12, r1 342; CHECK-LE-NEXT: pop {r4, pc} 343; 344; CHECK-BE-LABEL: and_user: 345; CHECK-BE: @ %bb.0: @ %entry 346; CHECK-BE-NEXT: .save {r4, r5, r6, lr} 347; CHECK-BE-NEXT: push {r4, r5, r6, lr} 348; CHECK-BE-NEXT: cmp r0, #1 349; CHECK-BE-NEXT: blt .LBB3_4 350; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader 351; CHECK-BE-NEXT: subs r2, #2 352; CHECK-BE-NEXT: subs r3, #2 353; CHECK-BE-NEXT: mov.w r12, #0 354; CHECK-BE-NEXT: movs r1, #0 355; CHECK-BE-NEXT: .p2align 2 356; CHECK-BE-NEXT: .LBB3_2: @ %for.body 357; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1 358; CHECK-BE-NEXT: ldrh lr, [r3, #2]! 359; CHECK-BE-NEXT: ldrsh r4, [r2, #2]! 360; CHECK-BE-NEXT: ldrsh.w r5, [r3, #2] 361; CHECK-BE-NEXT: ldrsh.w r6, [r2, #2] 362; CHECK-BE-NEXT: smlabb r4, r4, lr, r12 363; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 364; CHECK-BE-NEXT: subs r0, #1 365; CHECK-BE-NEXT: mul r1, lr, r1 366; CHECK-BE-NEXT: bne .LBB3_2 367; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup 368; CHECK-BE-NEXT: add.w r0, r12, r1 369; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 370; CHECK-BE-NEXT: .LBB3_4: 371; CHECK-BE-NEXT: mov.w r12, #0 372; CHECK-BE-NEXT: movs r1, #0 373; CHECK-BE-NEXT: add.w r0, r12, r1 374; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 375entry: 376 %cmp24 = icmp sgt i32 %arg, 0 377 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 378 379for.body.preheader: 380 %.pre = load i16, i16* %arg3, align 2 381 %.pre27 = load i16, i16* %arg2, align 2 382 br label %for.body 383 384for.cond.cleanup: 385 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 386 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ] 387 %res = add i32 %mac1.0.lcssa, %count.final 388 ret i32 %res 389 390for.body: 391 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 392 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 393 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ] 394 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 395 %0 = load i16, i16* %arrayidx, align 2 396 %add = add nuw nsw i32 %i.025, 1 397 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 398 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 399 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 400 %1 = load i16, i16* %arrayidx1, align 2 401 %2 = load i16, i16* %arrayidx3, align 2 402 %conv = sext i16 %2 to i32 403 %conv4 = sext i16 %0 to i32 404 %bottom = and i32 %conv4, 65535 405 %mul = mul nsw i32 %conv, %conv4 406 %3 = load i16, i16* %arrayidx6, align 2 407 %conv7 = sext i16 %3 to i32 408 %conv8 = sext i16 %1 to i32 409 %mul9 = mul nsw i32 %conv7, %conv8 410 %add10 = add i32 %mul, %mac1.026 411 %add11 = add i32 %mul9, %add10 412 %count.next = mul i32 %bottom, %count 413 %exitcond = icmp ne i32 %add, %arg 414 br i1 %exitcond, label %for.body, label %for.cond.cleanup 415} 416 417define i32 @multi_uses(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 418; CHECK-LE-LABEL: multi_uses: 419; CHECK-LE: @ %bb.0: @ %entry 420; CHECK-LE-NEXT: .save {r4, lr} 421; CHECK-LE-NEXT: push {r4, lr} 422; CHECK-LE-NEXT: cmp r0, #1 423; CHECK-LE-NEXT: blt .LBB4_4 424; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader 425; CHECK-LE-NEXT: subs r2, #2 426; CHECK-LE-NEXT: subs r3, #2 427; CHECK-LE-NEXT: mov.w lr, #0 428; CHECK-LE-NEXT: mov.w r12, #0 429; CHECK-LE-NEXT: .p2align 2 430; CHECK-LE-NEXT: .LBB4_2: @ %for.body 431; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1 432; CHECK-LE-NEXT: ldr r1, [r3, #2]! 433; CHECK-LE-NEXT: ldr r4, [r2, #2]! 434; CHECK-LE-NEXT: subs r0, #1 435; CHECK-LE-NEXT: smlad lr, r4, r1, lr 436; CHECK-LE-NEXT: eor.w r4, r1, r12 437; CHECK-LE-NEXT: mul r1, r4, r1 438; CHECK-LE-NEXT: lsl.w r12, r1, #16 439; CHECK-LE-NEXT: bne .LBB4_2 440; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup 441; CHECK-LE-NEXT: add.w r0, lr, r12 442; CHECK-LE-NEXT: pop {r4, pc} 443; CHECK-LE-NEXT: .LBB4_4: 444; CHECK-LE-NEXT: mov.w lr, #0 445; CHECK-LE-NEXT: mov.w r12, #0 446; CHECK-LE-NEXT: add.w r0, lr, r12 447; CHECK-LE-NEXT: pop {r4, pc} 448; 449; CHECK-BE-LABEL: multi_uses: 450; CHECK-BE: @ %bb.0: @ %entry 451; CHECK-BE-NEXT: .save {r4, r5, r6, lr} 452; CHECK-BE-NEXT: push {r4, r5, r6, lr} 453; CHECK-BE-NEXT: cmp r0, #1 454; CHECK-BE-NEXT: blt .LBB4_4 455; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader 456; CHECK-BE-NEXT: subs r2, #2 457; CHECK-BE-NEXT: subs r3, #2 458; CHECK-BE-NEXT: mov.w r12, #0 459; CHECK-BE-NEXT: mov.w lr, #0 460; CHECK-BE-NEXT: .p2align 2 461; CHECK-BE-NEXT: .LBB4_2: @ %for.body 462; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1 463; CHECK-BE-NEXT: ldrsh r1, [r3, #2]! 464; CHECK-BE-NEXT: ldrsh r4, [r2, #2]! 465; CHECK-BE-NEXT: ldrsh.w r5, [r3, #2] 466; CHECK-BE-NEXT: ldrsh.w r6, [r2, #2] 467; CHECK-BE-NEXT: smlabb r4, r4, r1, r12 468; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 469; CHECK-BE-NEXT: eor.w r6, r1, lr 470; CHECK-BE-NEXT: muls r1, r6, r1 471; CHECK-BE-NEXT: subs r0, #1 472; CHECK-BE-NEXT: lsl.w lr, r1, #16 473; CHECK-BE-NEXT: bne .LBB4_2 474; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup 475; CHECK-BE-NEXT: add.w r0, r12, lr 476; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 477; CHECK-BE-NEXT: .LBB4_4: 478; CHECK-BE-NEXT: mov.w r12, #0 479; CHECK-BE-NEXT: mov.w lr, #0 480; CHECK-BE-NEXT: add.w r0, r12, lr 481; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 482entry: 483 %cmp24 = icmp sgt i32 %arg, 0 484 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 485 486for.body.preheader: 487 %.pre = load i16, i16* %arg3, align 2 488 %.pre27 = load i16, i16* %arg2, align 2 489 br label %for.body 490 491for.cond.cleanup: 492 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 493 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ] 494 %res = add i32 %mac1.0.lcssa, %count.final 495 ret i32 %res 496 497for.body: 498 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 499 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 500 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ] 501 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 502 %0 = load i16, i16* %arrayidx, align 2 503 %add = add nuw nsw i32 %i.025, 1 504 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 505 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 506 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 507 %1 = load i16, i16* %arrayidx1, align 2 508 %2 = load i16, i16* %arrayidx3, align 2 509 %conv = sext i16 %2 to i32 510 %conv4 = sext i16 %0 to i32 511 %bottom = and i32 %conv4, 65535 512 %mul = mul nsw i32 %conv, %conv4 513 %3 = load i16, i16* %arrayidx6, align 2 514 %conv7 = sext i16 %3 to i32 515 %conv8 = sext i16 %1 to i32 516 %mul9 = mul nsw i32 %conv7, %conv8 517 %add10 = add i32 %mul, %mac1.026 518 %shl = shl i32 %conv4, 16 519 %add11 = add i32 %mul9, %add10 520 %xor = xor i32 %bottom, %count 521 %count.next = mul i32 %xor, %shl 522 %exitcond = icmp ne i32 %add, %arg 523 br i1 %exitcond, label %for.body, label %for.cond.cleanup 524} 525