563 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s3 4declare { i128, i1 } @llvm.uadd.with.overflow.i128(i128, i128)5declare i128 @llvm.uadd.sat.i128(i128, i128)6 7declare { i128, i1 } @llvm.usub.with.overflow.i128(i128, i128)8declare i128 @llvm.usub.sat.i128(i128, i128)9 10declare { i128, i1 } @llvm.umul.with.overflow.i128(i128, i128)11declare i128 @llvm.umul.sat.i128(i128, i128)12 13declare { i128, i1 } @llvm.sadd.with.overflow.i128(i128, i128)14declare i128 @llvm.sadd.sat.i128(i128, i128)15 16declare { i128, i1 } @llvm.ssub.with.overflow.i128(i128, i128)17declare i128 @llvm.ssub.sat.i128(i128, i128)18 19declare { i128, i1 } @llvm.smul.with.overflow.i128(i128, i128)20declare i128 @llvm.smul.sat.i128(i128, i128)21 22define i128 @u128_add(i128 %x, i128 %y) {23; CHECK-LABEL: u128_add:24; CHECK: // %bb.0:25; CHECK-NEXT: adds x0, x0, x226; CHECK-NEXT: adc x1, x1, x327; CHECK-NEXT: ret28 %1 = add i128 %x, %y29 ret i128 %130}31 32define { i128, i8 } @u128_checked_add(i128 %x, i128 %y) {33; CHECK-LABEL: u128_checked_add:34; CHECK: // %bb.0:35; CHECK-NEXT: adds x0, x0, x236; CHECK-NEXT: adcs x1, x1, x337; CHECK-NEXT: cset w8, hs38; CHECK-NEXT: eor w2, w8, #0x139; CHECK-NEXT: ret40 %1 = tail call { i128, i1 } @llvm.uadd.with.overflow.i128(i128 %x, i128 %y)41 %2 = extractvalue { i128, i1 } %1, 042 %3 = extractvalue { i128, i1 } %1, 143 %4 = xor i1 %3, true44 %5 = zext i1 %4 to i845 %6 = insertvalue { i128, i8 } undef, i128 %2, 046 %7 = insertvalue { i128, i8 } %6, i8 %5, 147 ret { i128, i8 } %748}49 50define { i128, i8 } @u128_overflowing_add(i128 %x, i128 %y) {51; CHECK-LABEL: u128_overflowing_add:52; CHECK: // %bb.0:53; CHECK-NEXT: adds x0, x0, x254; CHECK-NEXT: adcs x1, x1, x355; CHECK-NEXT: cset w2, hs56; CHECK-NEXT: ret57 %1 = tail call { i128, i1 } @llvm.uadd.with.overflow.i128(i128 %x, i128 %y)58 %2 = extractvalue { i128, i1 } %1, 059 %3 = extractvalue { i128, i1 } %1, 160 %4 = zext i1 %3 to i861 %5 = insertvalue { i128, i8 } undef, i128 %2, 062 %6 = insertvalue { i128, i8 } %5, i8 %4, 163 ret { i128, i8 } %664}65 66define i128 @u128_saturating_add(i128 %x, i128 %y) {67; CHECK-LABEL: u128_saturating_add:68; CHECK: // %bb.0:69; CHECK-NEXT: adds x8, x0, x270; CHECK-NEXT: adcs x9, x1, x371; CHECK-NEXT: csinv x0, x8, xzr, lo72; CHECK-NEXT: csinv x1, x9, xzr, lo73; CHECK-NEXT: ret74 %1 = tail call i128 @llvm.uadd.sat.i128(i128 %x, i128 %y)75 ret i128 %176}77 78define i128 @u128_sub(i128 %x, i128 %y) {79; CHECK-LABEL: u128_sub:80; CHECK: // %bb.0:81; CHECK-NEXT: subs x0, x0, x282; CHECK-NEXT: sbc x1, x1, x383; CHECK-NEXT: ret84 %1 = sub i128 %x, %y85 ret i128 %186}87 88define { i128, i8 } @u128_checked_sub(i128 %x, i128 %y) {89; CHECK-LABEL: u128_checked_sub:90; CHECK: // %bb.0:91; CHECK-NEXT: subs x0, x0, x292; CHECK-NEXT: sbcs x1, x1, x393; CHECK-NEXT: cset w8, lo94; CHECK-NEXT: eor w2, w8, #0x195; CHECK-NEXT: ret96 %1 = tail call { i128, i1 } @llvm.usub.with.overflow.i128(i128 %x, i128 %y)97 %2 = extractvalue { i128, i1 } %1, 098 %3 = extractvalue { i128, i1 } %1, 199 %4 = xor i1 %3, true100 %5 = zext i1 %4 to i8101 %6 = insertvalue { i128, i8 } undef, i128 %2, 0102 %7 = insertvalue { i128, i8 } %6, i8 %5, 1103 ret { i128, i8 } %7104}105 106define { i128, i8 } @u128_overflowing_sub(i128 %x, i128 %y) {107; CHECK-LABEL: u128_overflowing_sub:108; CHECK: // %bb.0:109; CHECK-NEXT: subs x0, x0, x2110; CHECK-NEXT: sbcs x1, x1, x3111; CHECK-NEXT: cset w2, lo112; CHECK-NEXT: ret113 %1 = tail call { i128, i1 } @llvm.usub.with.overflow.i128(i128 %x, i128 %y)114 %2 = extractvalue { i128, i1 } %1, 0115 %3 = extractvalue { i128, i1 } %1, 1116 %4 = zext i1 %3 to i8117 %5 = insertvalue { i128, i8 } undef, i128 %2, 0118 %6 = insertvalue { i128, i8 } %5, i8 %4, 1119 ret { i128, i8 } %6120}121 122define i128 @u128_saturating_sub(i128 %x, i128 %y) {123; CHECK-LABEL: u128_saturating_sub:124; CHECK: // %bb.0:125; CHECK-NEXT: subs x8, x0, x2126; CHECK-NEXT: sbcs x9, x1, x3127; CHECK-NEXT: csel x0, xzr, x8, lo128; CHECK-NEXT: csel x1, xzr, x9, lo129; CHECK-NEXT: ret130 %1 = tail call i128 @llvm.usub.sat.i128(i128 %x, i128 %y)131 ret i128 %1132}133 134define i128 @i128_add(i128 %x, i128 %y) {135; CHECK-LABEL: i128_add:136; CHECK: // %bb.0:137; CHECK-NEXT: adds x0, x0, x2138; CHECK-NEXT: adc x1, x1, x3139; CHECK-NEXT: ret140 %1 = add i128 %x, %y141 ret i128 %1142}143 144define { i128, i8 } @i128_checked_add(i128 %x, i128 %y) {145; CHECK-LABEL: i128_checked_add:146; CHECK: // %bb.0:147; CHECK-NEXT: adds x0, x0, x2148; CHECK-NEXT: adcs x1, x1, x3149; CHECK-NEXT: cset w8, vs150; CHECK-NEXT: eor w2, w8, #0x1151; CHECK-NEXT: ret152 %1 = tail call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %x, i128 %y)153 %2 = extractvalue { i128, i1 } %1, 0154 %3 = extractvalue { i128, i1 } %1, 1155 %4 = xor i1 %3, true156 %5 = zext i1 %4 to i8157 %6 = insertvalue { i128, i8 } undef, i128 %2, 0158 %7 = insertvalue { i128, i8 } %6, i8 %5, 1159 ret { i128, i8 } %7160}161 162define { i128, i8 } @i128_overflowing_add(i128 %x, i128 %y) {163; CHECK-LABEL: i128_overflowing_add:164; CHECK: // %bb.0:165; CHECK-NEXT: adds x0, x0, x2166; CHECK-NEXT: adcs x1, x1, x3167; CHECK-NEXT: cset w2, vs168; CHECK-NEXT: ret169 %1 = tail call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %x, i128 %y)170 %2 = extractvalue { i128, i1 } %1, 0171 %3 = extractvalue { i128, i1 } %1, 1172 %4 = zext i1 %3 to i8173 %5 = insertvalue { i128, i8 } undef, i128 %2, 0174 %6 = insertvalue { i128, i8 } %5, i8 %4, 1175 ret { i128, i8 } %6176}177 178define i128 @i128_saturating_add(i128 %x, i128 %y) {179; CHECK-LABEL: i128_saturating_add:180; CHECK: // %bb.0:181; CHECK-NEXT: adds x8, x0, x2182; CHECK-NEXT: adcs x9, x1, x3183; CHECK-NEXT: asr x10, x9, #63184; CHECK-NEXT: eor x11, x10, #0x8000000000000000185; CHECK-NEXT: csel x0, x10, x8, vs186; CHECK-NEXT: csel x1, x11, x9, vs187; CHECK-NEXT: ret188 %1 = tail call i128 @llvm.sadd.sat.i128(i128 %x, i128 %y)189 ret i128 %1190}191 192define i128 @i128_sub(i128 %x, i128 %y) {193; CHECK-LABEL: i128_sub:194; CHECK: // %bb.0:195; CHECK-NEXT: subs x0, x0, x2196; CHECK-NEXT: sbc x1, x1, x3197; CHECK-NEXT: ret198 %1 = sub i128 %x, %y199 ret i128 %1200}201 202define { i128, i8 } @i128_checked_sub(i128 %x, i128 %y) {203; CHECK-LABEL: i128_checked_sub:204; CHECK: // %bb.0:205; CHECK-NEXT: subs x0, x0, x2206; CHECK-NEXT: sbcs x1, x1, x3207; CHECK-NEXT: cset w8, vs208; CHECK-NEXT: eor w2, w8, #0x1209; CHECK-NEXT: ret210 %1 = tail call { i128, i1 } @llvm.ssub.with.overflow.i128(i128 %x, i128 %y)211 %2 = extractvalue { i128, i1 } %1, 0212 %3 = extractvalue { i128, i1 } %1, 1213 %4 = xor i1 %3, true214 %5 = zext i1 %4 to i8215 %6 = insertvalue { i128, i8 } undef, i128 %2, 0216 %7 = insertvalue { i128, i8 } %6, i8 %5, 1217 ret { i128, i8 } %7218}219 220define { i128, i8 } @i128_overflowing_sub(i128 %x, i128 %y) {221; CHECK-LABEL: i128_overflowing_sub:222; CHECK: // %bb.0:223; CHECK-NEXT: subs x0, x0, x2224; CHECK-NEXT: sbcs x1, x1, x3225; CHECK-NEXT: cset w2, vs226; CHECK-NEXT: ret227 %1 = tail call { i128, i1 } @llvm.ssub.with.overflow.i128(i128 %x, i128 %y)228 %2 = extractvalue { i128, i1 } %1, 0229 %3 = extractvalue { i128, i1 } %1, 1230 %4 = zext i1 %3 to i8231 %5 = insertvalue { i128, i8 } undef, i128 %2, 0232 %6 = insertvalue { i128, i8 } %5, i8 %4, 1233 ret { i128, i8 } %6234}235 236define i128 @i128_saturating_sub(i128 %x, i128 %y) {237; CHECK-LABEL: i128_saturating_sub:238; CHECK: // %bb.0:239; CHECK-NEXT: subs x8, x0, x2240; CHECK-NEXT: sbcs x9, x1, x3241; CHECK-NEXT: asr x10, x9, #63242; CHECK-NEXT: eor x11, x10, #0x8000000000000000243; CHECK-NEXT: csel x0, x10, x8, vs244; CHECK-NEXT: csel x1, x11, x9, vs245; CHECK-NEXT: ret246 %1 = tail call i128 @llvm.ssub.sat.i128(i128 %x, i128 %y)247 ret i128 %1248}249 250define i128 @u128_mul(i128 %x, i128 %y) {251; CHECK-LABEL: u128_mul:252; CHECK: // %bb.0:253; CHECK-NEXT: umulh x8, x0, x2254; CHECK-NEXT: madd x8, x0, x3, x8255; CHECK-NEXT: mul x0, x0, x2256; CHECK-NEXT: madd x1, x1, x2, x8257; CHECK-NEXT: ret258 %1 = mul i128 %x, %y259 ret i128 %1260}261 262define { i128, i8 } @u128_checked_mul(i128 %x, i128 %y) {263; CHECK-LABEL: u128_checked_mul:264; CHECK: // %bb.0:265; CHECK-NEXT: orr x8, x1, x3266; CHECK-NEXT: cbz x8, .LBB17_2267; CHECK-NEXT: // %bb.1: // %overflow268; CHECK-NEXT: mul x9, x3, x0269; CHECK-NEXT: cmp x1, #0270; CHECK-NEXT: ccmp x3, #0, #4, ne271; CHECK-NEXT: umulh x10, x1, x2272; CHECK-NEXT: umulh x8, x3, x0273; CHECK-NEXT: madd x9, x1, x2, x9274; CHECK-NEXT: ccmp xzr, x10, #0, eq275; CHECK-NEXT: umulh x11, x0, x2276; CHECK-NEXT: ccmp xzr, x8, #0, eq277; CHECK-NEXT: mul x0, x0, x2278; CHECK-NEXT: cset w8, ne279; CHECK-NEXT: adds x1, x11, x9280; CHECK-NEXT: csinc w8, w8, wzr, lo281; CHECK-NEXT: eor w2, w8, #0x1282; CHECK-NEXT: ret283; CHECK-NEXT: .LBB17_2: // %overflow.no284; CHECK-NEXT: umulh x1, x0, x2285; CHECK-NEXT: mul x0, x0, x2286; CHECK-NEXT: eor w2, w8, #0x1287; CHECK-NEXT: ret288 %1 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %x, i128 %y)289 %2 = extractvalue { i128, i1 } %1, 0290 %3 = extractvalue { i128, i1 } %1, 1291 %4 = xor i1 %3, true292 %5 = zext i1 %4 to i8293 %6 = insertvalue { i128, i8 } undef, i128 %2, 0294 %7 = insertvalue { i128, i8 } %6, i8 %5, 1295 ret { i128, i8 } %7296}297 298define { i128, i8 } @u128_overflowing_mul(i128 %x, i128 %y) {299; CHECK-LABEL: u128_overflowing_mul:300; CHECK: // %bb.0:301; CHECK-NEXT: orr x8, x1, x3302; CHECK-NEXT: cbz x8, .LBB18_2303; CHECK-NEXT: // %bb.1: // %overflow304; CHECK-NEXT: mul x9, x3, x0305; CHECK-NEXT: cmp x1, #0306; CHECK-NEXT: ccmp x3, #0, #4, ne307; CHECK-NEXT: umulh x10, x1, x2308; CHECK-NEXT: umulh x8, x3, x0309; CHECK-NEXT: madd x9, x1, x2, x9310; CHECK-NEXT: ccmp xzr, x10, #0, eq311; CHECK-NEXT: umulh x11, x0, x2312; CHECK-NEXT: ccmp xzr, x8, #0, eq313; CHECK-NEXT: mul x0, x0, x2314; CHECK-NEXT: cset w8, ne315; CHECK-NEXT: adds x1, x11, x9316; CHECK-NEXT: csinc w2, w8, wzr, lo317; CHECK-NEXT: ret318; CHECK-NEXT: .LBB18_2: // %overflow.no319; CHECK-NEXT: umulh x1, x0, x2320; CHECK-NEXT: mul x0, x0, x2321; CHECK-NEXT: mov w2, wzr322; CHECK-NEXT: ret323 %1 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %x, i128 %y)324 %2 = extractvalue { i128, i1 } %1, 0325 %3 = extractvalue { i128, i1 } %1, 1326 %4 = zext i1 %3 to i8327 %5 = insertvalue { i128, i8 } undef, i128 %2, 0328 %6 = insertvalue { i128, i8 } %5, i8 %4, 1329 ret { i128, i8 } %6330}331 332define i128 @u128_saturating_mul(i128 %x, i128 %y) {333; CHECK-LABEL: u128_saturating_mul:334; CHECK: // %bb.0:335; CHECK-NEXT: orr x8, x1, x3336; CHECK-NEXT: cbz x8, .LBB19_2337; CHECK-NEXT: // %bb.1: // %overflow338; CHECK-NEXT: mul x8, x3, x0339; CHECK-NEXT: cmp x1, #0340; CHECK-NEXT: ccmp x3, #0, #4, ne341; CHECK-NEXT: umulh x10, x1, x2342; CHECK-NEXT: umulh x9, x3, x0343; CHECK-NEXT: madd x11, x1, x2, x8344; CHECK-NEXT: ccmp xzr, x10, #0, eq345; CHECK-NEXT: umulh x12, x0, x2346; CHECK-NEXT: ccmp xzr, x9, #0, eq347; CHECK-NEXT: mul x8, x0, x2348; CHECK-NEXT: cset w10, ne349; CHECK-NEXT: adds x9, x12, x11350; CHECK-NEXT: csinc w10, w10, wzr, lo351; CHECK-NEXT: b .LBB19_3352; CHECK-NEXT: .LBB19_2: // %overflow.no353; CHECK-NEXT: umulh x9, x0, x2354; CHECK-NEXT: mov w10, wzr355; CHECK-NEXT: mul x8, x0, x2356; CHECK-NEXT: .LBB19_3: // %overflow.res357; CHECK-NEXT: cmp w10, #0358; CHECK-NEXT: csinv x0, x8, xzr, eq359; CHECK-NEXT: csinv x1, x9, xzr, eq360; CHECK-NEXT: ret361 %1 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %x, i128 %y)362 %2 = extractvalue { i128, i1 } %1, 0363 %3 = extractvalue { i128, i1 } %1, 1364 %4 = select i1 %3, i128 -1, i128 %2365 ret i128 %4366}367 368define i128 @i128_mul(i128 %x, i128 %y) {369; CHECK-LABEL: i128_mul:370; CHECK: // %bb.0:371; CHECK-NEXT: umulh x8, x0, x2372; CHECK-NEXT: madd x8, x0, x3, x8373; CHECK-NEXT: mul x0, x0, x2374; CHECK-NEXT: madd x1, x1, x2, x8375; CHECK-NEXT: ret376 %1 = mul i128 %x, %y377 ret i128 %1378}379 380define { i128, i8 } @i128_checked_mul(i128 %x, i128 %y) {381; CHECK-LABEL: i128_checked_mul:382; CHECK: // %bb.0:383; CHECK-NEXT: eor x8, x3, x2, asr #63384; CHECK-NEXT: eor x9, x1, x0, asr #63385; CHECK-NEXT: orr x8, x9, x8386; CHECK-NEXT: cbz x8, .LBB21_2387; CHECK-NEXT: // %bb.1: // %overflow388; CHECK-NEXT: asr x9, x1, #63389; CHECK-NEXT: umulh x10, x0, x2390; CHECK-NEXT: asr x13, x3, #63391; CHECK-NEXT: mul x11, x1, x2392; CHECK-NEXT: umulh x8, x1, x2393; CHECK-NEXT: mul x9, x9, x2394; CHECK-NEXT: adds x10, x11, x10395; CHECK-NEXT: mul x14, x0, x3396; CHECK-NEXT: umulh x12, x0, x3397; CHECK-NEXT: adc x8, x8, x9398; CHECK-NEXT: mov x9, x1399; CHECK-NEXT: mul x13, x0, x13400; CHECK-NEXT: asr x11, x8, #63401; CHECK-NEXT: mul x15, x1, x3402; CHECK-NEXT: adds x1, x14, x10403; CHECK-NEXT: smulh x9, x9, x3404; CHECK-NEXT: adc x10, x12, x13405; CHECK-NEXT: asr x12, x10, #63406; CHECK-NEXT: adds x8, x8, x10407; CHECK-NEXT: asr x10, x1, #63408; CHECK-NEXT: mul x0, x0, x2409; CHECK-NEXT: adc x11, x11, x12410; CHECK-NEXT: adds x8, x15, x8411; CHECK-NEXT: adc x9, x9, x11412; CHECK-NEXT: cmp x8, x10413; CHECK-NEXT: ccmp x9, x10, #0, eq414; CHECK-NEXT: cset w8, ne415; CHECK-NEXT: eor w2, w8, #0x1416; CHECK-NEXT: ret417; CHECK-NEXT: .LBB21_2: // %overflow.no418; CHECK-NEXT: smulh x1, x0, x2419; CHECK-NEXT: mul x0, x0, x2420; CHECK-NEXT: eor w2, w8, #0x1421; CHECK-NEXT: ret422 %1 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %x, i128 %y)423 %2 = extractvalue { i128, i1 } %1, 0424 %3 = extractvalue { i128, i1 } %1, 1425 %4 = xor i1 %3, true426 %5 = zext i1 %4 to i8427 %6 = insertvalue { i128, i8 } undef, i128 %2, 0428 %7 = insertvalue { i128, i8 } %6, i8 %5, 1429 ret { i128, i8 } %7430}431 432define { i128, i8 } @i128_overflowing_mul(i128 %x, i128 %y) {433; CHECK-LABEL: i128_overflowing_mul:434; CHECK: // %bb.0:435; CHECK-NEXT: eor x8, x3, x2, asr #63436; CHECK-NEXT: eor x9, x1, x0, asr #63437; CHECK-NEXT: orr x8, x9, x8438; CHECK-NEXT: cbz x8, .LBB22_2439; CHECK-NEXT: // %bb.1: // %overflow440; CHECK-NEXT: asr x9, x1, #63441; CHECK-NEXT: umulh x10, x0, x2442; CHECK-NEXT: asr x13, x3, #63443; CHECK-NEXT: mul x11, x1, x2444; CHECK-NEXT: umulh x8, x1, x2445; CHECK-NEXT: mul x9, x9, x2446; CHECK-NEXT: adds x10, x11, x10447; CHECK-NEXT: mul x14, x0, x3448; CHECK-NEXT: umulh x12, x0, x3449; CHECK-NEXT: adc x8, x8, x9450; CHECK-NEXT: mov x9, x1451; CHECK-NEXT: mul x13, x0, x13452; CHECK-NEXT: asr x11, x8, #63453; CHECK-NEXT: mul x15, x1, x3454; CHECK-NEXT: adds x1, x14, x10455; CHECK-NEXT: smulh x9, x9, x3456; CHECK-NEXT: adc x10, x12, x13457; CHECK-NEXT: asr x12, x10, #63458; CHECK-NEXT: adds x8, x8, x10459; CHECK-NEXT: asr x10, x1, #63460; CHECK-NEXT: mul x0, x0, x2461; CHECK-NEXT: adc x11, x11, x12462; CHECK-NEXT: adds x8, x15, x8463; CHECK-NEXT: adc x9, x9, x11464; CHECK-NEXT: cmp x8, x10465; CHECK-NEXT: ccmp x9, x10, #0, eq466; CHECK-NEXT: cset w2, ne467; CHECK-NEXT: ret468; CHECK-NEXT: .LBB22_2: // %overflow.no469; CHECK-NEXT: smulh x1, x0, x2470; CHECK-NEXT: mul x0, x0, x2471; CHECK-NEXT: mov w2, wzr472; CHECK-NEXT: ret473 %1 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %x, i128 %y)474 %2 = extractvalue { i128, i1 } %1, 0475 %3 = extractvalue { i128, i1 } %1, 1476 %4 = zext i1 %3 to i8477 %5 = insertvalue { i128, i8 } undef, i128 %2, 0478 %6 = insertvalue { i128, i8 } %5, i8 %4, 1479 ret { i128, i8 } %6480}481 482define i128 @i128_saturating_mul(i128 %x, i128 %y) {483; CHECK-LABEL: i128_saturating_mul:484; CHECK: // %bb.0:485; CHECK-NEXT: eor x8, x3, x2, asr #63486; CHECK-NEXT: eor x9, x1, x0, asr #63487; CHECK-NEXT: orr x8, x9, x8488; CHECK-NEXT: cbz x8, .LBB23_2489; CHECK-NEXT: // %bb.1: // %overflow490; CHECK-NEXT: asr x9, x1, #63491; CHECK-NEXT: umulh x10, x0, x2492; CHECK-NEXT: asr x13, x3, #63493; CHECK-NEXT: mul x11, x1, x2494; CHECK-NEXT: umulh x8, x1, x2495; CHECK-NEXT: mul x9, x9, x2496; CHECK-NEXT: adds x10, x11, x10497; CHECK-NEXT: mul x14, x0, x3498; CHECK-NEXT: umulh x12, x0, x3499; CHECK-NEXT: adc x9, x8, x9500; CHECK-NEXT: mul x13, x0, x13501; CHECK-NEXT: adds x8, x14, x10502; CHECK-NEXT: mul x15, x1, x3503; CHECK-NEXT: asr x14, x8, #63504; CHECK-NEXT: smulh x10, x1, x3505; CHECK-NEXT: adc x11, x12, x13506; CHECK-NEXT: asr x12, x9, #63507; CHECK-NEXT: asr x13, x11, #63508; CHECK-NEXT: adds x11, x9, x11509; CHECK-NEXT: mul x9, x0, x2510; CHECK-NEXT: adc x12, x12, x13511; CHECK-NEXT: adds x11, x15, x11512; CHECK-NEXT: adc x10, x10, x12513; CHECK-NEXT: cmp x11, x14514; CHECK-NEXT: ccmp x10, x14, #0, eq515; CHECK-NEXT: cset w10, ne516; CHECK-NEXT: b .LBB23_3517; CHECK-NEXT: .LBB23_2: // %overflow.no518; CHECK-NEXT: smulh x8, x0, x2519; CHECK-NEXT: mov w10, wzr520; CHECK-NEXT: mul x9, x0, x2521; CHECK-NEXT: .LBB23_3: // %overflow.res522; CHECK-NEXT: eor x11, x3, x1523; CHECK-NEXT: cmp w10, #0524; CHECK-NEXT: asr x11, x11, #63525; CHECK-NEXT: eor x12, x11, #0x7fffffffffffffff526; CHECK-NEXT: csinv x0, x9, x11, eq527; CHECK-NEXT: csel x1, x12, x8, ne528; CHECK-NEXT: ret529 %1 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %x, i128 %y)530 %2 = extractvalue { i128, i1 } %1, 0531 %3 = extractvalue { i128, i1 } %1, 1532 %4 = xor i128 %y, %x533 %5 = icmp sgt i128 %4, -1534 %6 = select i1 %5, i128 170141183460469231731687303715884105727, i128 -170141183460469231731687303715884105728535 %7 = select i1 %3, i128 %6, i128 %2536 ret i128 %7537}538 539define { i128, i1 } @saddo_not_1(i128 %x) nounwind {540; CHECK-LABEL: saddo_not_1:541; CHECK: // %bb.0:542; CHECK-NEXT: negs x0, x0543; CHECK-NEXT: ngcs x1, x1544; CHECK-NEXT: cset w2, vs545; CHECK-NEXT: ret546 %not = xor i128 %x, -1547 %r = call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %not, i128 1)548 ret { i128, i1 } %r549}550 551define { i128, i1 } @saddo_carry_not_1(i128 %x) nounwind {552; CHECK-LABEL: saddo_carry_not_1:553; CHECK: // %bb.0:554; CHECK-NEXT: mov w8, #1 // =0x1555; CHECK-NEXT: negs x0, x0556; CHECK-NEXT: sbcs x1, x8, x1557; CHECK-NEXT: cset w2, vs558; CHECK-NEXT: ret559 %not = xor i128 %x, -1560 %r = call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %not, i128 u0x10000000000000001)561 ret { i128, i1 } %r562}563