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: sxtah r1, r1, lr 24; CHECK-LE-NEXT: smlad r12, r4, lr, r12 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 r4, [r2, #2]! 51; CHECK-BE-NEXT: ldrsh.w r5, [r3, #2] 52; CHECK-BE-NEXT: ldrsh.w r6, [r2, #2] 53; CHECK-BE-NEXT: smlabb r4, r4, lr, r12 54; CHECK-BE-NEXT: subs r0, #1 55; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 56; CHECK-BE-NEXT: add r1, lr 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: subs r0, #1 158; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 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, r5, r7, lr} 214; CHECK-LE-NEXT: push {r4, r5, r7, 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 r4, [r2, #2]! 226; CHECK-LE-NEXT: ldr lr, [r3, #2]! 227; CHECK-LE-NEXT: asrs r5, r4, #16 228; CHECK-LE-NEXT: smlad r12, r4, lr, r12 229; CHECK-LE-NEXT: subs r0, #1 230; CHECK-LE-NEXT: mul r1, r5, 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, r5, r7, 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, r5, r7, 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: subs r0, #1 261; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 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, r5, r7, lr} 317; CHECK-LE-NEXT: push {r4, r5, r7, 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: uxth r5, r2 331; CHECK-LE-NEXT: smlad r12, r4, r2, r12 332; CHECK-LE-NEXT: subs r0, #1 333; CHECK-LE-NEXT: mul r1, r5, 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, r5, r7, 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, r5, r7, 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: ldrsh 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: uxth.w lr, lr 364; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 365; CHECK-BE-NEXT: subs r0, #1 366; CHECK-BE-NEXT: mul r1, lr, r1 367; CHECK-BE-NEXT: bne .LBB3_2 368; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup 369; CHECK-BE-NEXT: add.w r0, r12, r1 370; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 371; CHECK-BE-NEXT: .LBB3_4: 372; CHECK-BE-NEXT: mov.w r12, #0 373; CHECK-BE-NEXT: movs r1, #0 374; CHECK-BE-NEXT: add.w r0, r12, r1 375; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 376entry: 377 %cmp24 = icmp sgt i32 %arg, 0 378 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 379 380for.body.preheader: 381 %.pre = load i16, i16* %arg3, align 2 382 %.pre27 = load i16, i16* %arg2, align 2 383 br label %for.body 384 385for.cond.cleanup: 386 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 387 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ] 388 %res = add i32 %mac1.0.lcssa, %count.final 389 ret i32 %res 390 391for.body: 392 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 393 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 394 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ] 395 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 396 %0 = load i16, i16* %arrayidx, align 2 397 %add = add nuw nsw i32 %i.025, 1 398 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 399 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 400 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 401 %1 = load i16, i16* %arrayidx1, align 2 402 %2 = load i16, i16* %arrayidx3, align 2 403 %conv = sext i16 %2 to i32 404 %conv4 = sext i16 %0 to i32 405 %bottom = and i32 %conv4, 65535 406 %mul = mul nsw i32 %conv, %conv4 407 %3 = load i16, i16* %arrayidx6, align 2 408 %conv7 = sext i16 %3 to i32 409 %conv8 = sext i16 %1 to i32 410 %mul9 = mul nsw i32 %conv7, %conv8 411 %add10 = add i32 %mul, %mac1.026 412 %add11 = add i32 %mul9, %add10 413 %count.next = mul i32 %bottom, %count 414 %exitcond = icmp ne i32 %add, %arg 415 br i1 %exitcond, label %for.body, label %for.cond.cleanup 416} 417 418define i32 @multi_uses(i32 %arg, i32* nocapture readnone %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 419; CHECK-LE-LABEL: multi_uses: 420; CHECK-LE: @ %bb.0: @ %entry 421; CHECK-LE-NEXT: .save {r4, r5, r7, lr} 422; CHECK-LE-NEXT: push {r4, r5, r7, lr} 423; CHECK-LE-NEXT: cmp r0, #1 424; CHECK-LE-NEXT: blt .LBB4_4 425; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader 426; CHECK-LE-NEXT: subs r2, #2 427; CHECK-LE-NEXT: subs r3, #2 428; CHECK-LE-NEXT: mov.w lr, #0 429; CHECK-LE-NEXT: mov.w r12, #0 430; CHECK-LE-NEXT: .p2align 2 431; CHECK-LE-NEXT: .LBB4_2: @ %for.body 432; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1 433; CHECK-LE-NEXT: ldr r1, [r3, #2]! 434; CHECK-LE-NEXT: ldr r4, [r2, #2]! 435; CHECK-LE-NEXT: sxth r5, r1 436; CHECK-LE-NEXT: smlad lr, r4, r1, lr 437; CHECK-LE-NEXT: eor.w r1, r5, r12 438; CHECK-LE-NEXT: muls r1, r5, r1 439; CHECK-LE-NEXT: subs r0, #1 440; CHECK-LE-NEXT: lsl.w r12, r1, #16 441; CHECK-LE-NEXT: bne .LBB4_2 442; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup 443; CHECK-LE-NEXT: add.w r0, lr, r12 444; CHECK-LE-NEXT: pop {r4, r5, r7, pc} 445; CHECK-LE-NEXT: .LBB4_4: 446; CHECK-LE-NEXT: mov.w lr, #0 447; CHECK-LE-NEXT: mov.w r12, #0 448; CHECK-LE-NEXT: add.w r0, lr, r12 449; CHECK-LE-NEXT: pop {r4, r5, r7, pc} 450; 451; CHECK-BE-LABEL: multi_uses: 452; CHECK-BE: @ %bb.0: @ %entry 453; CHECK-BE-NEXT: .save {r4, r5, r6, lr} 454; CHECK-BE-NEXT: push {r4, r5, r6, lr} 455; CHECK-BE-NEXT: cmp r0, #1 456; CHECK-BE-NEXT: blt .LBB4_4 457; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader 458; CHECK-BE-NEXT: subs r2, #2 459; CHECK-BE-NEXT: subs r3, #2 460; CHECK-BE-NEXT: mov.w r12, #0 461; CHECK-BE-NEXT: mov.w lr, #0 462; CHECK-BE-NEXT: .p2align 2 463; CHECK-BE-NEXT: .LBB4_2: @ %for.body 464; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1 465; CHECK-BE-NEXT: ldrsh r1, [r3, #2]! 466; CHECK-BE-NEXT: ldrsh r4, [r2, #2]! 467; CHECK-BE-NEXT: ldrsh.w r5, [r3, #2] 468; CHECK-BE-NEXT: ldrsh.w r6, [r2, #2] 469; CHECK-BE-NEXT: smlabb r4, r4, r1, r12 470; CHECK-BE-NEXT: subs r0, #1 471; CHECK-BE-NEXT: smlabb r12, r6, r5, r4 472; CHECK-BE-NEXT: eor.w r6, r1, lr 473; CHECK-BE-NEXT: mul r1, r6, r1 474; CHECK-BE-NEXT: lsl.w lr, r1, #16 475; CHECK-BE-NEXT: bne .LBB4_2 476; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup 477; CHECK-BE-NEXT: add.w r0, r12, lr 478; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 479; CHECK-BE-NEXT: .LBB4_4: 480; CHECK-BE-NEXT: mov.w r12, #0 481; CHECK-BE-NEXT: mov.w lr, #0 482; CHECK-BE-NEXT: add.w r0, r12, lr 483; CHECK-BE-NEXT: pop {r4, r5, r6, pc} 484entry: 485 %cmp24 = icmp sgt i32 %arg, 0 486 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 487 488for.body.preheader: 489 %.pre = load i16, i16* %arg3, align 2 490 %.pre27 = load i16, i16* %arg2, align 2 491 br label %for.body 492 493for.cond.cleanup: 494 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 495 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ] 496 %res = add i32 %mac1.0.lcssa, %count.final 497 ret i32 %res 498 499for.body: 500 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 501 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 502 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ] 503 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 504 %0 = load i16, i16* %arrayidx, align 2 505 %add = add nuw nsw i32 %i.025, 1 506 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 507 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 508 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 509 %1 = load i16, i16* %arrayidx1, align 2 510 %2 = load i16, i16* %arrayidx3, align 2 511 %conv = sext i16 %2 to i32 512 %conv4 = sext i16 %0 to i32 513 %bottom = and i32 %conv4, 65535 514 %mul = mul nsw i32 %conv, %conv4 515 %3 = load i16, i16* %arrayidx6, align 2 516 %conv7 = sext i16 %3 to i32 517 %conv8 = sext i16 %1 to i32 518 %mul9 = mul nsw i32 %conv7, %conv8 519 %add10 = add i32 %mul, %mac1.026 520 %shl = shl i32 %conv4, 16 521 %add11 = add i32 %mul9, %add10 522 %xor = xor i32 %bottom, %count 523 %count.next = mul i32 %xor, %shl 524 %exitcond = icmp ne i32 %add, %arg 525 br i1 %exitcond, label %for.body, label %for.cond.cleanup 526} 527