1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=armv6-unknown-linux-gnu | FileCheck %s --check-prefixes=ARMV6 3; RUN: llc < %s -mtriple=armv7-unknown-linux-gnu | FileCheck %s --check-prefixes=ARMV7 4 5define { i128, i8 } @muloti_test(i128 %l, i128 %r) unnamed_addr #0 { 6; ARMV6-LABEL: muloti_test: 7; ARMV6: @ %bb.0: @ %start 8; ARMV6-NEXT: push {r4, r5, r6, r7, r8, r9, r10, r11, lr} 9; ARMV6-NEXT: sub sp, sp, #28 10; ARMV6-NEXT: ldr r4, [sp, #72] 11; ARMV6-NEXT: mov r7, r0 12; ARMV6-NEXT: str r0, [sp, #4] @ 4-byte Spill 13; ARMV6-NEXT: ldr r12, [sp, #64] 14; ARMV6-NEXT: umull r1, r0, r2, r4 15; ARMV6-NEXT: ldr r5, [sp, #68] 16; ARMV6-NEXT: str r1, [r7] 17; ARMV6-NEXT: ldr r1, [sp, #76] 18; ARMV6-NEXT: umull r7, r6, r1, r12 19; ARMV6-NEXT: str r6, [sp, #8] @ 4-byte Spill 20; ARMV6-NEXT: umull r6, r9, r5, r4 21; ARMV6-NEXT: add r7, r6, r7 22; ARMV6-NEXT: umull r4, r6, r12, r4 23; ARMV6-NEXT: str r4, [sp, #16] @ 4-byte Spill 24; ARMV6-NEXT: mov r4, #0 25; ARMV6-NEXT: adds r8, r6, r7 26; ARMV6-NEXT: ldr r6, [sp, #80] 27; ARMV6-NEXT: adc r7, r4, #0 28; ARMV6-NEXT: ldr r4, [sp, #84] 29; ARMV6-NEXT: str r7, [sp, #24] @ 4-byte Spill 30; ARMV6-NEXT: umull r12, lr, r3, r6 31; ARMV6-NEXT: umull r11, r7, r4, r2 32; ARMV6-NEXT: add r12, r11, r12 33; ARMV6-NEXT: umull r11, r10, r6, r2 34; ARMV6-NEXT: adds r12, r10, r12 35; ARMV6-NEXT: mov r10, #0 36; ARMV6-NEXT: adc r6, r10, #0 37; ARMV6-NEXT: str r6, [sp, #20] @ 4-byte Spill 38; ARMV6-NEXT: ldr r6, [sp, #16] @ 4-byte Reload 39; ARMV6-NEXT: adds r6, r6, r11 40; ARMV6-NEXT: str r6, [sp, #12] @ 4-byte Spill 41; ARMV6-NEXT: adc r6, r8, r12 42; ARMV6-NEXT: str r6, [sp, #16] @ 4-byte Spill 43; ARMV6-NEXT: ldr r6, [sp, #72] 44; ARMV6-NEXT: mov r12, #0 45; ARMV6-NEXT: umull r2, r8, r2, r1 46; ARMV6-NEXT: umlal r0, r12, r3, r6 47; ARMV6-NEXT: adds r0, r2, r0 48; ARMV6-NEXT: ldr r2, [sp, #4] @ 4-byte Reload 49; ARMV6-NEXT: adcs r8, r12, r8 50; ARMV6-NEXT: adc r12, r10, #0 51; ARMV6-NEXT: cmp lr, #0 52; ARMV6-NEXT: str r0, [r2, #4] 53; ARMV6-NEXT: movne lr, #1 54; ARMV6-NEXT: ldr r11, [sp, #8] @ 4-byte Reload 55; ARMV6-NEXT: cmp r7, #0 56; ARMV6-NEXT: movne r7, #1 57; ARMV6-NEXT: ldr r0, [sp, #64] 58; ARMV6-NEXT: cmp r11, #0 59; ARMV6-NEXT: umlal r8, r12, r3, r1 60; ARMV6-NEXT: movne r11, #1 61; ARMV6-NEXT: cmp r9, #0 62; ARMV6-NEXT: movne r9, #1 63; ARMV6-NEXT: orrs r10, r0, r5 64; ARMV6-NEXT: ldr r0, [sp, #80] 65; ARMV6-NEXT: movne r10, #1 66; ARMV6-NEXT: ldr r6, [sp, #12] @ 4-byte Reload 67; ARMV6-NEXT: orrs r0, r0, r4 68; ARMV6-NEXT: movne r0, #1 69; ARMV6-NEXT: cmp r4, #0 70; ARMV6-NEXT: movne r4, #1 71; ARMV6-NEXT: cmp r3, #0 72; ARMV6-NEXT: movne r3, #1 73; ARMV6-NEXT: cmp r5, #0 74; ARMV6-NEXT: movne r5, #1 75; ARMV6-NEXT: cmp r1, #0 76; ARMV6-NEXT: movne r1, #1 77; ARMV6-NEXT: adds r6, r8, r6 78; ARMV6-NEXT: str r6, [r2, #8] 79; ARMV6-NEXT: and r1, r5, r1 80; ARMV6-NEXT: ldr r6, [sp, #16] @ 4-byte Reload 81; ARMV6-NEXT: orr r1, r1, r9 82; ARMV6-NEXT: orr r1, r1, r11 83; ARMV6-NEXT: and r0, r10, r0 84; ARMV6-NEXT: adcs r6, r12, r6 85; ARMV6-NEXT: str r6, [r2, #12] 86; ARMV6-NEXT: ldr r6, [sp, #24] @ 4-byte Reload 87; ARMV6-NEXT: orr r1, r1, r6 88; ARMV6-NEXT: orr r0, r0, r1 89; ARMV6-NEXT: and r1, r4, r3 90; ARMV6-NEXT: orr r1, r1, r7 91; ARMV6-NEXT: ldr r3, [sp, #20] @ 4-byte Reload 92; ARMV6-NEXT: orr r1, r1, lr 93; ARMV6-NEXT: orr r1, r1, r3 94; ARMV6-NEXT: orr r0, r0, r1 95; ARMV6-NEXT: mov r1, #0 96; ARMV6-NEXT: adc r1, r1, #0 97; ARMV6-NEXT: orr r0, r0, r1 98; ARMV6-NEXT: and r0, r0, #1 99; ARMV6-NEXT: strb r0, [r2, #16] 100; ARMV6-NEXT: add sp, sp, #28 101; ARMV6-NEXT: pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} 102; 103; ARMV7-LABEL: muloti_test: 104; ARMV7: @ %bb.0: @ %start 105; ARMV7-NEXT: push {r4, r5, r6, r7, r8, r9, r10, r11, lr} 106; ARMV7-NEXT: sub sp, sp, #44 107; ARMV7-NEXT: ldr r8, [sp, #88] 108; ARMV7-NEXT: mov r9, r0 109; ARMV7-NEXT: ldr r7, [sp, #96] 110; ARMV7-NEXT: ldr lr, [sp, #100] 111; ARMV7-NEXT: umull r0, r5, r2, r8 112; ARMV7-NEXT: ldr r4, [sp, #80] 113; ARMV7-NEXT: str r0, [sp, #32] @ 4-byte Spill 114; ARMV7-NEXT: umull r1, r0, r3, r7 115; ARMV7-NEXT: str r0, [sp, #4] @ 4-byte Spill 116; ARMV7-NEXT: umull r0, r11, lr, r2 117; ARMV7-NEXT: str r1, [sp, #20] @ 4-byte Spill 118; ARMV7-NEXT: ldr r1, [sp, #92] 119; ARMV7-NEXT: str r0, [sp] @ 4-byte Spill 120; ARMV7-NEXT: umull r0, r10, r7, r2 121; ARMV7-NEXT: mov r7, r1 122; ARMV7-NEXT: umull r6, r12, r1, r4 123; ARMV7-NEXT: str r0, [sp, #40] @ 4-byte Spill 124; ARMV7-NEXT: ldr r0, [sp, #84] 125; ARMV7-NEXT: str r6, [sp, #24] @ 4-byte Spill 126; ARMV7-NEXT: umull r6, r1, r0, r8 127; ARMV7-NEXT: str r6, [sp, #16] @ 4-byte Spill 128; ARMV7-NEXT: umull r6, r2, r2, r7 129; ARMV7-NEXT: mov r7, r4 130; ARMV7-NEXT: str r6, [sp, #8] @ 4-byte Spill 131; ARMV7-NEXT: str r2, [sp, #12] @ 4-byte Spill 132; ARMV7-NEXT: umull r2, r6, r4, r8 133; ARMV7-NEXT: str r2, [sp, #36] @ 4-byte Spill 134; ARMV7-NEXT: ldr r2, [sp, #32] @ 4-byte Reload 135; ARMV7-NEXT: str r6, [sp, #28] @ 4-byte Spill 136; ARMV7-NEXT: mov r6, #0 137; ARMV7-NEXT: str r2, [r9] 138; ARMV7-NEXT: umlal r5, r6, r3, r8 139; ARMV7-NEXT: ldr r2, [sp, #20] @ 4-byte Reload 140; ARMV7-NEXT: ldr r4, [sp] @ 4-byte Reload 141; ARMV7-NEXT: add r4, r4, r2 142; ARMV7-NEXT: adds r2, r10, r4 143; ARMV7-NEXT: str r2, [sp, #20] @ 4-byte Spill 144; ARMV7-NEXT: mov r2, #0 145; ARMV7-NEXT: adc r2, r2, #0 146; ARMV7-NEXT: cmp r12, #0 147; ARMV7-NEXT: str r2, [sp, #32] @ 4-byte Spill 148; ARMV7-NEXT: movwne r12, #1 149; ARMV7-NEXT: cmp r1, #0 150; ARMV7-NEXT: ldr r2, [sp, #96] 151; ARMV7-NEXT: movwne r1, #1 152; ARMV7-NEXT: orrs r10, r7, r0 153; ARMV7-NEXT: movwne r10, #1 154; ARMV7-NEXT: orrs r7, r2, lr 155; ARMV7-NEXT: ldr r2, [sp, #92] 156; ARMV7-NEXT: movwne r7, #1 157; ARMV7-NEXT: cmp r0, #0 158; ARMV7-NEXT: movwne r0, #1 159; ARMV7-NEXT: cmp r2, #0 160; ARMV7-NEXT: mov r4, r2 161; ARMV7-NEXT: mov r8, r2 162; ARMV7-NEXT: ldr r2, [sp, #8] @ 4-byte Reload 163; ARMV7-NEXT: movwne r4, #1 164; ARMV7-NEXT: and r0, r0, r4 165; ARMV7-NEXT: mov r4, #0 166; ARMV7-NEXT: adds r5, r2, r5 167; ARMV7-NEXT: str r5, [r9, #4] 168; ARMV7-NEXT: orr r0, r0, r1 169; ARMV7-NEXT: ldr r1, [sp, #24] @ 4-byte Reload 170; ARMV7-NEXT: ldr r2, [sp, #16] @ 4-byte Reload 171; ARMV7-NEXT: and r5, r10, r7 172; ARMV7-NEXT: orr r0, r0, r12 173; ARMV7-NEXT: mov r12, #0 174; ARMV7-NEXT: add r1, r2, r1 175; ARMV7-NEXT: ldr r2, [sp, #12] @ 4-byte Reload 176; ARMV7-NEXT: adcs r2, r6, r2 177; ARMV7-NEXT: ldr r6, [sp, #28] @ 4-byte Reload 178; ARMV7-NEXT: adc r7, r4, #0 179; ARMV7-NEXT: adds r1, r6, r1 180; ARMV7-NEXT: umlal r2, r7, r3, r8 181; ARMV7-NEXT: adc r4, r4, #0 182; ARMV7-NEXT: orr r0, r0, r4 183; ARMV7-NEXT: orr r0, r5, r0 184; ARMV7-NEXT: ldr r4, [sp, #40] @ 4-byte Reload 185; ARMV7-NEXT: ldr r5, [sp, #36] @ 4-byte Reload 186; ARMV7-NEXT: adds r5, r5, r4 187; ARMV7-NEXT: ldr r4, [sp, #20] @ 4-byte Reload 188; ARMV7-NEXT: adc r1, r1, r4 189; ARMV7-NEXT: ldr r4, [sp, #4] @ 4-byte Reload 190; ARMV7-NEXT: cmp r4, #0 191; ARMV7-NEXT: movwne r4, #1 192; ARMV7-NEXT: cmp r3, #0 193; ARMV7-NEXT: movwne r3, #1 194; ARMV7-NEXT: cmp lr, #0 195; ARMV7-NEXT: movwne lr, #1 196; ARMV7-NEXT: cmp r11, #0 197; ARMV7-NEXT: movwne r11, #1 198; ARMV7-NEXT: adds r2, r2, r5 199; ARMV7-NEXT: and r3, lr, r3 200; ARMV7-NEXT: str r2, [r9, #8] 201; ARMV7-NEXT: adcs r1, r7, r1 202; ARMV7-NEXT: str r1, [r9, #12] 203; ARMV7-NEXT: orr r1, r3, r11 204; ARMV7-NEXT: ldr r2, [sp, #32] @ 4-byte Reload 205; ARMV7-NEXT: orr r1, r1, r4 206; ARMV7-NEXT: orr r1, r1, r2 207; ARMV7-NEXT: orr r0, r0, r1 208; ARMV7-NEXT: adc r1, r12, #0 209; ARMV7-NEXT: orr r0, r0, r1 210; ARMV7-NEXT: and r0, r0, #1 211; ARMV7-NEXT: strb r0, [r9, #16] 212; ARMV7-NEXT: add sp, sp, #44 213; ARMV7-NEXT: pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} 214start: 215 %0 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %l, i128 %r) #2 216 %1 = extractvalue { i128, i1 } %0, 0 217 %2 = extractvalue { i128, i1 } %0, 1 218 %3 = zext i1 %2 to i8 219 %4 = insertvalue { i128, i8 } undef, i128 %1, 0 220 %5 = insertvalue { i128, i8 } %4, i8 %3, 1 221 ret { i128, i8 } %5 222} 223 224; Function Attrs: nounwind readnone speculatable 225declare { i128, i1 } @llvm.umul.with.overflow.i128(i128, i128) #1 226 227attributes #0 = { nounwind readnone uwtable } 228attributes #1 = { nounwind readnone speculatable } 229attributes #2 = { nounwind } 230