1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s 3 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, x2 26; CHECK-NEXT: adc x1, x1, x3 27; CHECK-NEXT: ret 28 %1 = add i128 %x, %y 29 ret i128 %1 30} 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, x2 36; CHECK-NEXT: adcs x1, x1, x3 37; CHECK-NEXT: cset w8, hs 38; CHECK-NEXT: eor w2, w8, #0x1 39; CHECK-NEXT: ret 40 %1 = tail call { i128, i1 } @llvm.uadd.with.overflow.i128(i128 %x, i128 %y) 41 %2 = extractvalue { i128, i1 } %1, 0 42 %3 = extractvalue { i128, i1 } %1, 1 43 %4 = xor i1 %3, true 44 %5 = zext i1 %4 to i8 45 %6 = insertvalue { i128, i8 } undef, i128 %2, 0 46 %7 = insertvalue { i128, i8 } %6, i8 %5, 1 47 ret { i128, i8 } %7 48} 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, x2 54; CHECK-NEXT: adcs x1, x1, x3 55; CHECK-NEXT: cset w2, hs 56; CHECK-NEXT: ret 57 %1 = tail call { i128, i1 } @llvm.uadd.with.overflow.i128(i128 %x, i128 %y) 58 %2 = extractvalue { i128, i1 } %1, 0 59 %3 = extractvalue { i128, i1 } %1, 1 60 %4 = zext i1 %3 to i8 61 %5 = insertvalue { i128, i8 } undef, i128 %2, 0 62 %6 = insertvalue { i128, i8 } %5, i8 %4, 1 63 ret { i128, i8 } %6 64} 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, x2 70; CHECK-NEXT: adcs x9, x1, x3 71; CHECK-NEXT: csinv x0, x8, xzr, lo 72; CHECK-NEXT: csinv x1, x9, xzr, lo 73; CHECK-NEXT: ret 74 %1 = tail call i128 @llvm.uadd.sat.i128(i128 %x, i128 %y) 75 ret i128 %1 76} 77 78define i128 @u128_sub(i128 %x, i128 %y) { 79; CHECK-LABEL: u128_sub: 80; CHECK: // %bb.0: 81; CHECK-NEXT: subs x0, x0, x2 82; CHECK-NEXT: sbc x1, x1, x3 83; CHECK-NEXT: ret 84 %1 = sub i128 %x, %y 85 ret i128 %1 86} 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, x2 92; CHECK-NEXT: sbcs x1, x1, x3 93; CHECK-NEXT: cset w8, lo 94; CHECK-NEXT: eor w2, w8, #0x1 95; CHECK-NEXT: ret 96 %1 = tail call { i128, i1 } @llvm.usub.with.overflow.i128(i128 %x, i128 %y) 97 %2 = extractvalue { i128, i1 } %1, 0 98 %3 = extractvalue { i128, i1 } %1, 1 99 %4 = xor i1 %3, true 100 %5 = zext i1 %4 to i8 101 %6 = insertvalue { i128, i8 } undef, i128 %2, 0 102 %7 = insertvalue { i128, i8 } %6, i8 %5, 1 103 ret { i128, i8 } %7 104} 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, x2 110; CHECK-NEXT: sbcs x1, x1, x3 111; CHECK-NEXT: cset w2, lo 112; CHECK-NEXT: ret 113 %1 = tail call { i128, i1 } @llvm.usub.with.overflow.i128(i128 %x, i128 %y) 114 %2 = extractvalue { i128, i1 } %1, 0 115 %3 = extractvalue { i128, i1 } %1, 1 116 %4 = zext i1 %3 to i8 117 %5 = insertvalue { i128, i8 } undef, i128 %2, 0 118 %6 = insertvalue { i128, i8 } %5, i8 %4, 1 119 ret { i128, i8 } %6 120} 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, x2 126; CHECK-NEXT: sbcs x9, x1, x3 127; CHECK-NEXT: csel x0, xzr, x8, lo 128; CHECK-NEXT: csel x1, xzr, x9, lo 129; CHECK-NEXT: ret 130 %1 = tail call i128 @llvm.usub.sat.i128(i128 %x, i128 %y) 131 ret i128 %1 132} 133 134define i128 @i128_add(i128 %x, i128 %y) { 135; CHECK-LABEL: i128_add: 136; CHECK: // %bb.0: 137; CHECK-NEXT: adds x0, x0, x2 138; CHECK-NEXT: adc x1, x1, x3 139; CHECK-NEXT: ret 140 %1 = add i128 %x, %y 141 ret i128 %1 142} 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, x2 148; CHECK-NEXT: adcs x1, x1, x3 149; CHECK-NEXT: cset w8, vs 150; CHECK-NEXT: eor w2, w8, #0x1 151; CHECK-NEXT: ret 152 %1 = tail call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %x, i128 %y) 153 %2 = extractvalue { i128, i1 } %1, 0 154 %3 = extractvalue { i128, i1 } %1, 1 155 %4 = xor i1 %3, true 156 %5 = zext i1 %4 to i8 157 %6 = insertvalue { i128, i8 } undef, i128 %2, 0 158 %7 = insertvalue { i128, i8 } %6, i8 %5, 1 159 ret { i128, i8 } %7 160} 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, x2 166; CHECK-NEXT: adcs x1, x1, x3 167; CHECK-NEXT: cset w2, vs 168; CHECK-NEXT: ret 169 %1 = tail call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %x, i128 %y) 170 %2 = extractvalue { i128, i1 } %1, 0 171 %3 = extractvalue { i128, i1 } %1, 1 172 %4 = zext i1 %3 to i8 173 %5 = insertvalue { i128, i8 } undef, i128 %2, 0 174 %6 = insertvalue { i128, i8 } %5, i8 %4, 1 175 ret { i128, i8 } %6 176} 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, x2 182; CHECK-NEXT: adcs x9, x1, x3 183; CHECK-NEXT: asr x10, x9, #63 184; CHECK-NEXT: eor x11, x10, #0x8000000000000000 185; CHECK-NEXT: csel x0, x10, x8, vs 186; CHECK-NEXT: csel x1, x11, x9, vs 187; CHECK-NEXT: ret 188 %1 = tail call i128 @llvm.sadd.sat.i128(i128 %x, i128 %y) 189 ret i128 %1 190} 191 192define i128 @i128_sub(i128 %x, i128 %y) { 193; CHECK-LABEL: i128_sub: 194; CHECK: // %bb.0: 195; CHECK-NEXT: subs x0, x0, x2 196; CHECK-NEXT: sbc x1, x1, x3 197; CHECK-NEXT: ret 198 %1 = sub i128 %x, %y 199 ret i128 %1 200} 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, x2 206; CHECK-NEXT: sbcs x1, x1, x3 207; CHECK-NEXT: cset w8, vs 208; CHECK-NEXT: eor w2, w8, #0x1 209; CHECK-NEXT: ret 210 %1 = tail call { i128, i1 } @llvm.ssub.with.overflow.i128(i128 %x, i128 %y) 211 %2 = extractvalue { i128, i1 } %1, 0 212 %3 = extractvalue { i128, i1 } %1, 1 213 %4 = xor i1 %3, true 214 %5 = zext i1 %4 to i8 215 %6 = insertvalue { i128, i8 } undef, i128 %2, 0 216 %7 = insertvalue { i128, i8 } %6, i8 %5, 1 217 ret { i128, i8 } %7 218} 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, x2 224; CHECK-NEXT: sbcs x1, x1, x3 225; CHECK-NEXT: cset w2, vs 226; CHECK-NEXT: ret 227 %1 = tail call { i128, i1 } @llvm.ssub.with.overflow.i128(i128 %x, i128 %y) 228 %2 = extractvalue { i128, i1 } %1, 0 229 %3 = extractvalue { i128, i1 } %1, 1 230 %4 = zext i1 %3 to i8 231 %5 = insertvalue { i128, i8 } undef, i128 %2, 0 232 %6 = insertvalue { i128, i8 } %5, i8 %4, 1 233 ret { i128, i8 } %6 234} 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, x2 240; CHECK-NEXT: sbcs x9, x1, x3 241; CHECK-NEXT: asr x10, x9, #63 242; CHECK-NEXT: eor x11, x10, #0x8000000000000000 243; CHECK-NEXT: csel x0, x10, x8, vs 244; CHECK-NEXT: csel x1, x11, x9, vs 245; CHECK-NEXT: ret 246 %1 = tail call i128 @llvm.ssub.sat.i128(i128 %x, i128 %y) 247 ret i128 %1 248} 249 250define i128 @u128_mul(i128 %x, i128 %y) { 251; CHECK-LABEL: u128_mul: 252; CHECK: // %bb.0: 253; CHECK-NEXT: umulh x8, x0, x2 254; CHECK-NEXT: madd x8, x0, x3, x8 255; CHECK-NEXT: mul x0, x0, x2 256; CHECK-NEXT: madd x1, x1, x2, x8 257; CHECK-NEXT: ret 258 %1 = mul i128 %x, %y 259 ret i128 %1 260} 261 262define { i128, i8 } @u128_checked_mul(i128 %x, i128 %y) { 263; CHECK-LABEL: u128_checked_mul: 264; CHECK: // %bb.0: 265; CHECK-NEXT: mul x9, x3, x0 266; CHECK-NEXT: cmp x1, #0 267; CHECK-NEXT: ccmp x3, #0, #4, ne 268; CHECK-NEXT: umulh x8, x1, x2 269; CHECK-NEXT: umulh x10, x3, x0 270; CHECK-NEXT: madd x9, x1, x2, x9 271; CHECK-NEXT: ccmp xzr, x8, #0, eq 272; CHECK-NEXT: umulh x11, x0, x2 273; CHECK-NEXT: ccmp xzr, x10, #0, eq 274; CHECK-NEXT: mul x0, x0, x2 275; CHECK-NEXT: cset w8, ne 276; CHECK-NEXT: adds x1, x11, x9 277; CHECK-NEXT: csinc w8, w8, wzr, lo 278; CHECK-NEXT: eor w2, w8, #0x1 279; CHECK-NEXT: ret 280 %1 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %x, i128 %y) 281 %2 = extractvalue { i128, i1 } %1, 0 282 %3 = extractvalue { i128, i1 } %1, 1 283 %4 = xor i1 %3, true 284 %5 = zext i1 %4 to i8 285 %6 = insertvalue { i128, i8 } undef, i128 %2, 0 286 %7 = insertvalue { i128, i8 } %6, i8 %5, 1 287 ret { i128, i8 } %7 288} 289 290define { i128, i8 } @u128_overflowing_mul(i128 %x, i128 %y) { 291; CHECK-LABEL: u128_overflowing_mul: 292; CHECK: // %bb.0: 293; CHECK-NEXT: mul x9, x3, x0 294; CHECK-NEXT: cmp x1, #0 295; CHECK-NEXT: ccmp x3, #0, #4, ne 296; CHECK-NEXT: umulh x8, x1, x2 297; CHECK-NEXT: umulh x10, x3, x0 298; CHECK-NEXT: madd x9, x1, x2, x9 299; CHECK-NEXT: ccmp xzr, x8, #0, eq 300; CHECK-NEXT: umulh x11, x0, x2 301; CHECK-NEXT: ccmp xzr, x10, #0, eq 302; CHECK-NEXT: mul x0, x0, x2 303; CHECK-NEXT: cset w8, ne 304; CHECK-NEXT: adds x1, x11, x9 305; CHECK-NEXT: csinc w2, w8, wzr, lo 306; CHECK-NEXT: ret 307 %1 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %x, i128 %y) 308 %2 = extractvalue { i128, i1 } %1, 0 309 %3 = extractvalue { i128, i1 } %1, 1 310 %4 = zext i1 %3 to i8 311 %5 = insertvalue { i128, i8 } undef, i128 %2, 0 312 %6 = insertvalue { i128, i8 } %5, i8 %4, 1 313 ret { i128, i8 } %6 314} 315 316define i128 @u128_saturating_mul(i128 %x, i128 %y) { 317; CHECK-LABEL: u128_saturating_mul: 318; CHECK: // %bb.0: 319; CHECK-NEXT: mul x9, x3, x0 320; CHECK-NEXT: cmp x1, #0 321; CHECK-NEXT: ccmp x3, #0, #4, ne 322; CHECK-NEXT: umulh x8, x1, x2 323; CHECK-NEXT: umulh x10, x3, x0 324; CHECK-NEXT: madd x9, x1, x2, x9 325; CHECK-NEXT: ccmp xzr, x8, #0, eq 326; CHECK-NEXT: umulh x11, x0, x2 327; CHECK-NEXT: ccmp xzr, x10, #0, eq 328; CHECK-NEXT: mul x8, x0, x2 329; CHECK-NEXT: cset w10, ne 330; CHECK-NEXT: adds x9, x11, x9 331; CHECK-NEXT: csinc w10, w10, wzr, lo 332; CHECK-NEXT: cmp w10, #0 333; CHECK-NEXT: csinv x0, x8, xzr, eq 334; CHECK-NEXT: csinv x1, x9, xzr, eq 335; CHECK-NEXT: ret 336 %1 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %x, i128 %y) 337 %2 = extractvalue { i128, i1 } %1, 0 338 %3 = extractvalue { i128, i1 } %1, 1 339 %4 = select i1 %3, i128 -1, i128 %2 340 ret i128 %4 341} 342 343define i128 @i128_mul(i128 %x, i128 %y) { 344; CHECK-LABEL: i128_mul: 345; CHECK: // %bb.0: 346; CHECK-NEXT: umulh x8, x0, x2 347; CHECK-NEXT: madd x8, x0, x3, x8 348; CHECK-NEXT: mul x0, x0, x2 349; CHECK-NEXT: madd x1, x1, x2, x8 350; CHECK-NEXT: ret 351 %1 = mul i128 %x, %y 352 ret i128 %1 353} 354 355define { i128, i8 } @i128_checked_mul(i128 %x, i128 %y) { 356; CHECK-LABEL: i128_checked_mul: 357; CHECK: // %bb.0: 358; CHECK-NEXT: asr x9, x1, #63 359; CHECK-NEXT: umulh x10, x0, x2 360; CHECK-NEXT: asr x13, x3, #63 361; CHECK-NEXT: mul x11, x1, x2 362; CHECK-NEXT: umulh x8, x1, x2 363; CHECK-NEXT: mul x9, x9, x2 364; CHECK-NEXT: adds x10, x11, x10 365; CHECK-NEXT: mul x14, x0, x3 366; CHECK-NEXT: umulh x12, x0, x3 367; CHECK-NEXT: adc x9, x8, x9 368; CHECK-NEXT: mul x13, x0, x13 369; CHECK-NEXT: adds x8, x14, x10 370; CHECK-NEXT: mul x15, x1, x3 371; CHECK-NEXT: smulh x10, x1, x3 372; CHECK-NEXT: mov x1, x8 373; CHECK-NEXT: adc x11, x12, x13 374; CHECK-NEXT: asr x12, x9, #63 375; CHECK-NEXT: asr x13, x11, #63 376; CHECK-NEXT: adds x9, x9, x11 377; CHECK-NEXT: asr x11, x8, #63 378; CHECK-NEXT: mul x0, x0, x2 379; CHECK-NEXT: adc x12, x12, x13 380; CHECK-NEXT: adds x9, x15, x9 381; CHECK-NEXT: adc x10, x10, x12 382; CHECK-NEXT: cmp x9, x11 383; CHECK-NEXT: ccmp x10, x11, #0, eq 384; CHECK-NEXT: cset w2, eq 385; CHECK-NEXT: ret 386 %1 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %x, i128 %y) 387 %2 = extractvalue { i128, i1 } %1, 0 388 %3 = extractvalue { i128, i1 } %1, 1 389 %4 = xor i1 %3, true 390 %5 = zext i1 %4 to i8 391 %6 = insertvalue { i128, i8 } undef, i128 %2, 0 392 %7 = insertvalue { i128, i8 } %6, i8 %5, 1 393 ret { i128, i8 } %7 394} 395 396define { i128, i8 } @i128_overflowing_mul(i128 %x, i128 %y) { 397; CHECK-LABEL: i128_overflowing_mul: 398; CHECK: // %bb.0: 399; CHECK-NEXT: asr x9, x1, #63 400; CHECK-NEXT: umulh x10, x0, x2 401; CHECK-NEXT: asr x13, x3, #63 402; CHECK-NEXT: mul x11, x1, x2 403; CHECK-NEXT: umulh x8, x1, x2 404; CHECK-NEXT: mul x9, x9, x2 405; CHECK-NEXT: adds x10, x11, x10 406; CHECK-NEXT: mul x14, x0, x3 407; CHECK-NEXT: umulh x12, x0, x3 408; CHECK-NEXT: adc x9, x8, x9 409; CHECK-NEXT: mul x13, x0, x13 410; CHECK-NEXT: adds x8, x14, x10 411; CHECK-NEXT: mul x15, x1, x3 412; CHECK-NEXT: smulh x10, x1, x3 413; CHECK-NEXT: mov x1, x8 414; CHECK-NEXT: adc x11, x12, x13 415; CHECK-NEXT: asr x12, x9, #63 416; CHECK-NEXT: asr x13, x11, #63 417; CHECK-NEXT: adds x9, x9, x11 418; CHECK-NEXT: asr x11, x8, #63 419; CHECK-NEXT: mul x0, x0, x2 420; CHECK-NEXT: adc x12, x12, x13 421; CHECK-NEXT: adds x9, x15, x9 422; CHECK-NEXT: adc x10, x10, x12 423; CHECK-NEXT: cmp x9, x11 424; CHECK-NEXT: ccmp x10, x11, #0, eq 425; CHECK-NEXT: cset w2, ne 426; CHECK-NEXT: ret 427 %1 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %x, i128 %y) 428 %2 = extractvalue { i128, i1 } %1, 0 429 %3 = extractvalue { i128, i1 } %1, 1 430 %4 = zext i1 %3 to i8 431 %5 = insertvalue { i128, i8 } undef, i128 %2, 0 432 %6 = insertvalue { i128, i8 } %5, i8 %4, 1 433 ret { i128, i8 } %6 434} 435 436define i128 @i128_saturating_mul(i128 %x, i128 %y) { 437; CHECK-LABEL: i128_saturating_mul: 438; CHECK: // %bb.0: 439; CHECK-NEXT: asr x9, x1, #63 440; CHECK-NEXT: umulh x10, x0, x2 441; CHECK-NEXT: asr x13, x3, #63 442; CHECK-NEXT: mul x11, x1, x2 443; CHECK-NEXT: umulh x8, x1, x2 444; CHECK-NEXT: mul x9, x9, x2 445; CHECK-NEXT: adds x10, x11, x10 446; CHECK-NEXT: mul x14, x0, x3 447; CHECK-NEXT: umulh x12, x0, x3 448; CHECK-NEXT: adc x8, x8, x9 449; CHECK-NEXT: mul x13, x0, x13 450; CHECK-NEXT: adds x9, x14, x10 451; CHECK-NEXT: mul x11, x1, x3 452; CHECK-NEXT: adc x10, x12, x13 453; CHECK-NEXT: smulh x12, x1, x3 454; CHECK-NEXT: asr x13, x8, #63 455; CHECK-NEXT: asr x14, x10, #63 456; CHECK-NEXT: adds x8, x8, x10 457; CHECK-NEXT: adc x10, x13, x14 458; CHECK-NEXT: adds x8, x11, x8 459; CHECK-NEXT: asr x11, x9, #63 460; CHECK-NEXT: mul x13, x0, x2 461; CHECK-NEXT: adc x10, x12, x10 462; CHECK-NEXT: eor x12, x3, x1 463; CHECK-NEXT: eor x8, x8, x11 464; CHECK-NEXT: eor x10, x10, x11 465; CHECK-NEXT: asr x11, x12, #63 466; CHECK-NEXT: orr x8, x8, x10 467; CHECK-NEXT: eor x10, x11, #0x7fffffffffffffff 468; CHECK-NEXT: cmp x8, #0 469; CHECK-NEXT: csinv x0, x13, x11, eq 470; CHECK-NEXT: csel x1, x10, x9, ne 471; CHECK-NEXT: ret 472 %1 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %x, i128 %y) 473 %2 = extractvalue { i128, i1 } %1, 0 474 %3 = extractvalue { i128, i1 } %1, 1 475 %4 = xor i128 %y, %x 476 %5 = icmp sgt i128 %4, -1 477 %6 = select i1 %5, i128 170141183460469231731687303715884105727, i128 -170141183460469231731687303715884105728 478 %7 = select i1 %3, i128 %6, i128 %2 479 ret i128 %7 480} 481 482define { i128, i1 } @saddo_not_1(i128 %x) nounwind { 483; CHECK-LABEL: saddo_not_1: 484; CHECK: // %bb.0: 485; CHECK-NEXT: negs x0, x0 486; CHECK-NEXT: ngcs x1, x1 487; CHECK-NEXT: cset w2, vs 488; CHECK-NEXT: ret 489 %not = xor i128 %x, -1 490 %r = call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %not, i128 1) 491 ret { i128, i1 } %r 492} 493 494define { i128, i1 } @saddo_carry_not_1(i128 %x) nounwind { 495; CHECK-LABEL: saddo_carry_not_1: 496; CHECK: // %bb.0: 497; CHECK-NEXT: mov w8, #1 // =0x1 498; CHECK-NEXT: negs x0, x0 499; CHECK-NEXT: sbcs x1, x8, x1 500; CHECK-NEXT: cset w2, vs 501; CHECK-NEXT: ret 502 %not = xor i128 %x, -1 503 %r = call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %not, i128 u0x10000000000000001) 504 ret { i128, i1 } %r 505} 506