1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=sparc-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC 3; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC64 4 5define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind { 6; SPARC-LABEL: muloti_test: 7; SPARC: ! %bb.0: ! %start 8; SPARC-NEXT: save %sp, -96, %sp 9; SPARC-NEXT: ld [%fp+96], %l2 10; SPARC-NEXT: mov %i3, %g2 11; SPARC-NEXT: mov %i2, %g3 12; SPARC-NEXT: umul %i1, %l2, %l0 13; SPARC-NEXT: rd %y, %i2 14; SPARC-NEXT: ld [%fp+92], %l1 15; SPARC-NEXT: umul %i0, %l2, %i3 16; SPARC-NEXT: rd %y, %g4 17; SPARC-NEXT: addcc %i3, %i2, %i2 18; SPARC-NEXT: addxcc %g4, 0, %i3 19; SPARC-NEXT: umul %i1, %l1, %g4 20; SPARC-NEXT: rd %y, %l3 21; SPARC-NEXT: addcc %g4, %i2, %l4 22; SPARC-NEXT: addxcc %l3, 0, %i2 23; SPARC-NEXT: addcc %i3, %i2, %i2 24; SPARC-NEXT: addxcc %g0, 0, %i3 25; SPARC-NEXT: umul %i0, %l1, %g4 26; SPARC-NEXT: rd %y, %l3 27; SPARC-NEXT: addcc %g4, %i2, %i2 28; SPARC-NEXT: sra %i0, 31, %g4 29; SPARC-NEXT: smul %l1, %g4, %l5 30; SPARC-NEXT: umul %l2, %g4, %l6 31; SPARC-NEXT: rd %y, %l7 32; SPARC-NEXT: addxcc %l3, %i3, %l3 33; SPARC-NEXT: add %l7, %l6, %i3 34; SPARC-NEXT: add %i3, %l5, %l5 35; SPARC-NEXT: addcc %i2, %l6, %l6 36; SPARC-NEXT: umul %g2, %l2, %i3 37; SPARC-NEXT: rd %y, %i2 38; SPARC-NEXT: addxcc %l3, %l5, %l3 39; SPARC-NEXT: umul %g3, %l2, %l2 40; SPARC-NEXT: rd %y, %l5 41; SPARC-NEXT: addcc %l2, %i2, %i2 42; SPARC-NEXT: addxcc %l5, 0, %l2 43; SPARC-NEXT: umul %g2, %l1, %l5 44; SPARC-NEXT: rd %y, %l7 45; SPARC-NEXT: addcc %l5, %i2, %i2 46; SPARC-NEXT: addxcc %l7, 0, %l5 47; SPARC-NEXT: addcc %l2, %l5, %l2 48; SPARC-NEXT: addxcc %g0, 0, %l5 49; SPARC-NEXT: umul %g3, %l1, %l1 50; SPARC-NEXT: rd %y, %l7 51; SPARC-NEXT: addcc %l1, %l2, %l1 52; SPARC-NEXT: addxcc %l7, %l5, %l2 53; SPARC-NEXT: addcc %l0, %l1, %l0 54; SPARC-NEXT: addxcc %l4, %l2, %l1 55; SPARC-NEXT: addxcc %l6, 0, %l2 56; SPARC-NEXT: addxcc %l3, 0, %l3 57; SPARC-NEXT: umul %g2, %i5, %l4 58; SPARC-NEXT: rd %y, %l5 59; SPARC-NEXT: sra %l3, 31, %l6 60; SPARC-NEXT: umul %g3, %i5, %l7 61; SPARC-NEXT: rd %y, %o0 62; SPARC-NEXT: addcc %l7, %l5, %l5 63; SPARC-NEXT: addxcc %o0, 0, %l7 64; SPARC-NEXT: umul %g2, %i4, %o0 65; SPARC-NEXT: rd %y, %o1 66; SPARC-NEXT: addcc %o0, %l5, %l5 67; SPARC-NEXT: addxcc %o1, 0, %o0 68; SPARC-NEXT: addcc %l7, %o0, %l7 69; SPARC-NEXT: addxcc %g0, 0, %o0 70; SPARC-NEXT: umul %g3, %i4, %o1 71; SPARC-NEXT: rd %y, %o2 72; SPARC-NEXT: addcc %o1, %l7, %l7 73; SPARC-NEXT: sra %i4, 31, %o1 74; SPARC-NEXT: smul %o1, %g3, %g3 75; SPARC-NEXT: umul %o1, %g2, %g2 76; SPARC-NEXT: rd %y, %o3 77; SPARC-NEXT: addxcc %o2, %o0, %o0 78; SPARC-NEXT: add %o3, %g3, %g3 79; SPARC-NEXT: add %g3, %g2, %g3 80; SPARC-NEXT: addcc %l7, %g2, %l7 81; SPARC-NEXT: addxcc %o0, %g3, %o0 82; SPARC-NEXT: addcc %l4, %l0, %g2 83; SPARC-NEXT: addxcc %l5, %l1, %g3 84; SPARC-NEXT: addxcc %l7, 0, %l0 85; SPARC-NEXT: addxcc %o0, 0, %l1 86; SPARC-NEXT: sra %l1, 31, %l4 87; SPARC-NEXT: addcc %l2, %l0, %l0 88; SPARC-NEXT: addxcc %l3, %l1, %l1 89; SPARC-NEXT: addxcc %l6, %l4, %l2 90; SPARC-NEXT: smul %i4, %g4, %l3 91; SPARC-NEXT: umul %i5, %g4, %g4 92; SPARC-NEXT: rd %y, %l5 93; SPARC-NEXT: addxcc %l6, %l4, %l4 94; SPARC-NEXT: add %l5, %g4, %l5 95; SPARC-NEXT: smul %o1, %i0, %l6 96; SPARC-NEXT: umul %o1, %i1, %l7 97; SPARC-NEXT: rd %y, %o0 98; SPARC-NEXT: add %l5, %l3, %l3 99; SPARC-NEXT: add %o0, %l6, %l5 100; SPARC-NEXT: add %l5, %l7, %l5 101; SPARC-NEXT: addcc %l7, %g4, %g4 102; SPARC-NEXT: umul %i1, %i5, %l6 103; SPARC-NEXT: rd %y, %l7 104; SPARC-NEXT: addxcc %l5, %l3, %l3 105; SPARC-NEXT: umul %i0, %i5, %i5 106; SPARC-NEXT: rd %y, %l5 107; SPARC-NEXT: addcc %i5, %l7, %i5 108; SPARC-NEXT: addxcc %l5, 0, %l5 109; SPARC-NEXT: umul %i1, %i4, %i1 110; SPARC-NEXT: rd %y, %l7 111; SPARC-NEXT: addcc %i1, %i5, %i1 112; SPARC-NEXT: addxcc %l7, 0, %i5 113; SPARC-NEXT: addcc %l5, %i5, %i5 114; SPARC-NEXT: addxcc %g0, 0, %l5 115; SPARC-NEXT: umul %i0, %i4, %i0 116; SPARC-NEXT: rd %y, %i4 117; SPARC-NEXT: addcc %i0, %i5, %i0 118; SPARC-NEXT: addxcc %i4, %l5, %i4 119; SPARC-NEXT: addcc %i0, %g4, %i0 120; SPARC-NEXT: addxcc %i4, %l3, %i4 121; SPARC-NEXT: addcc %l6, %l0, %i5 122; SPARC-NEXT: addxcc %i1, %l1, %i1 123; SPARC-NEXT: addxcc %i0, %l2, %i0 124; SPARC-NEXT: addxcc %i4, %l4, %i4 125; SPARC-NEXT: sra %g3, 31, %g4 126; SPARC-NEXT: xor %i4, %g4, %i4 127; SPARC-NEXT: xor %i1, %g4, %i1 128; SPARC-NEXT: or %i1, %i4, %i1 129; SPARC-NEXT: xor %i0, %g4, %i0 130; SPARC-NEXT: xor %i5, %g4, %i4 131; SPARC-NEXT: or %i4, %i0, %i0 132; SPARC-NEXT: or %i0, %i1, %i0 133; SPARC-NEXT: cmp %i0, 0 134; SPARC-NEXT: bne .LBB0_2 135; SPARC-NEXT: nop 136; SPARC-NEXT: ! %bb.1: ! %start 137; SPARC-NEXT: ba .LBB0_3 138; SPARC-NEXT: mov %g0, %i4 139; SPARC-NEXT: .LBB0_2: 140; SPARC-NEXT: mov 1, %i4 141; SPARC-NEXT: .LBB0_3: ! %start 142; SPARC-NEXT: mov %g3, %i0 143; SPARC-NEXT: ret 144; SPARC-NEXT: restore %g0, %g2, %o1 145; 146; SPARC64-LABEL: muloti_test: 147; SPARC64: .register %g2, #scratch 148; SPARC64-NEXT: .register %g3, #scratch 149; SPARC64-NEXT: ! %bb.0: ! %start 150; SPARC64-NEXT: save %sp, -176, %sp 151; SPARC64-NEXT: mov %i3, %i4 152; SPARC64-NEXT: mov %i1, %i5 153; SPARC64-NEXT: mov %i0, %l2 154; SPARC64-NEXT: srax %i0, 63, %i3 155; SPARC64-NEXT: mov %i3, %o0 156; SPARC64-NEXT: mov %i0, %o1 157; SPARC64-NEXT: mov %g0, %o2 158; SPARC64-NEXT: call __multi3 159; SPARC64-NEXT: mov %i4, %o3 160; SPARC64-NEXT: mov %o0, %l0 161; SPARC64-NEXT: mov %o1, %l1 162; SPARC64-NEXT: mov %g0, %o0 163; SPARC64-NEXT: mov %i1, %o1 164; SPARC64-NEXT: mov %g0, %o2 165; SPARC64-NEXT: call __multi3 166; SPARC64-NEXT: mov %i4, %o3 167; SPARC64-NEXT: mov %o1, %i1 168; SPARC64-NEXT: mov %g0, %i0 169; SPARC64-NEXT: add %l1, %o0, %l3 170; SPARC64-NEXT: cmp %l3, %l1 171; SPARC64-NEXT: movcs %xcc, 1, %i0 172; SPARC64-NEXT: srl %i0, 0, %i0 173; SPARC64-NEXT: add %l0, %i0, %l0 174; SPARC64-NEXT: srax %l0, 63, %l1 175; SPARC64-NEXT: srax %i2, 63, %i4 176; SPARC64-NEXT: mov %g0, %o0 177; SPARC64-NEXT: mov %i5, %o1 178; SPARC64-NEXT: mov %i4, %o2 179; SPARC64-NEXT: call __multi3 180; SPARC64-NEXT: mov %i2, %o3 181; SPARC64-NEXT: mov %g0, %i5 182; SPARC64-NEXT: mov %g0, %g2 183; SPARC64-NEXT: add %o1, %l3, %i0 184; SPARC64-NEXT: cmp %i0, %o1 185; SPARC64-NEXT: movcs %xcc, 1, %i5 186; SPARC64-NEXT: srl %i5, 0, %i5 187; SPARC64-NEXT: add %o0, %i5, %i5 188; SPARC64-NEXT: srax %i5, 63, %g3 189; SPARC64-NEXT: add %l1, %g3, %g3 190; SPARC64-NEXT: add %l0, %i5, %i5 191; SPARC64-NEXT: cmp %i5, %l0 192; SPARC64-NEXT: movcs %xcc, 1, %g2 193; SPARC64-NEXT: srl %g2, 0, %g2 194; SPARC64-NEXT: add %g3, %g2, %l0 195; SPARC64-NEXT: mov %i3, %o0 196; SPARC64-NEXT: mov %l2, %o1 197; SPARC64-NEXT: mov %i4, %o2 198; SPARC64-NEXT: call __multi3 199; SPARC64-NEXT: mov %i2, %o3 200; SPARC64-NEXT: mov %g0, %i2 201; SPARC64-NEXT: mov %g0, %i3 202; SPARC64-NEXT: add %o0, %l0, %i4 203; SPARC64-NEXT: add %o1, %i5, %i5 204; SPARC64-NEXT: cmp %i5, %o1 205; SPARC64-NEXT: movcs %xcc, 1, %i2 206; SPARC64-NEXT: srl %i2, 0, %i2 207; SPARC64-NEXT: add %i4, %i2, %i2 208; SPARC64-NEXT: srax %i0, 63, %i4 209; SPARC64-NEXT: xor %i2, %i4, %i2 210; SPARC64-NEXT: xor %i5, %i4, %i4 211; SPARC64-NEXT: or %i4, %i2, %i2 212; SPARC64-NEXT: movrnz %i2, 1, %i3 213; SPARC64-NEXT: srl %i3, 0, %i2 214; SPARC64-NEXT: ret 215; SPARC64-NEXT: restore 216start: 217 %0 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %l, i128 %r) 218 %1 = extractvalue { i128, i1 } %0, 0 219 %2 = extractvalue { i128, i1 } %0, 1 220 %3 = zext i1 %2 to i8 221 %4 = insertvalue { i128, i8 } undef, i128 %1, 0 222 %5 = insertvalue { i128, i8 } %4, i8 %3, 1 223 ret { i128, i8 } %5 224} 225 226declare { i128, i1 } @llvm.smul.with.overflow.i128(i128, i128) 227