| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | 
 | ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s | 
 |  | 
 | declare { i256, i1 } @llvm.uadd.with.overflow.i256(i256, i256) | 
 | declare   i256       @llvm.uadd.sat.i256(i256, i256) | 
 |  | 
 | declare { i256, i1 } @llvm.usub.with.overflow.i256(i256, i256) | 
 | declare   i256       @llvm.usub.sat.i256(i256, i256) | 
 |  | 
 | declare { i256, i1 } @llvm.sadd.with.overflow.i256(i256, i256) | 
 | declare   i256       @llvm.sadd.sat.i256(i256, i256) | 
 |  | 
 | declare { i256, i1 } @llvm.ssub.with.overflow.i256(i256, i256) | 
 | declare   i256       @llvm.ssub.sat.i256(i256, i256) | 
 |  | 
 | define i256 @u256_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x0, x0, x4 | 
 | ; CHECK-NEXT:    adcs x1, x1, x5 | 
 | ; CHECK-NEXT:    adcs x2, x2, x6 | 
 | ; CHECK-NEXT:    adc x3, x3, x7 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = add i256 %x, %y | 
 |   ret i256 %1 | 
 | } | 
 |  | 
 | define { i256, i8 } @u256_checked_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_checked_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x0, x0, x4 | 
 | ; CHECK-NEXT:    adcs x1, x1, x5 | 
 | ; CHECK-NEXT:    adcs x2, x2, x6 | 
 | ; CHECK-NEXT:    adcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w8, hs | 
 | ; CHECK-NEXT:    eor w4, w8, #0x1 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.uadd.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = xor i1 %3, true | 
 |   %5 = zext i1 %4 to i8 | 
 |   %6 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %7 = insertvalue { i256, i8 } %6, i8 %5, 1 | 
 |   ret { i256, i8 } %7 | 
 | } | 
 |  | 
 | define { i256, i8 } @u256_overflowing_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_overflowing_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x0, x0, x4 | 
 | ; CHECK-NEXT:    adcs x1, x1, x5 | 
 | ; CHECK-NEXT:    adcs x2, x2, x6 | 
 | ; CHECK-NEXT:    adcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w4, hs | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.uadd.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = zext i1 %3 to i8 | 
 |   %5 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %6 = insertvalue { i256, i8 } %5, i8 %4, 1 | 
 |   ret { i256, i8 } %6 | 
 | } | 
 |  | 
 | define i256 @u256_saturating_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_saturating_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x8, x0, x4 | 
 | ; CHECK-NEXT:    adcs x9, x1, x5 | 
 | ; CHECK-NEXT:    adcs x10, x2, x6 | 
 | ; CHECK-NEXT:    adcs x11, x3, x7 | 
 | ; CHECK-NEXT:    csinv x0, x8, xzr, lo | 
 | ; CHECK-NEXT:    csinv x1, x9, xzr, lo | 
 | ; CHECK-NEXT:    csinv x2, x10, xzr, lo | 
 | ; CHECK-NEXT:    csinv x3, x11, xzr, lo | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call i256 @llvm.uadd.sat.i256(i256 %x, i256 %y) | 
 |   ret i256 %1 | 
 | } | 
 |  | 
 | define i256 @u256_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x0, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x1, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x2, x2, x6 | 
 | ; CHECK-NEXT:    sbc x3, x3, x7 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = sub i256 %x, %y | 
 |   ret i256 %1 | 
 | } | 
 |  | 
 | define { i256, i8 } @u256_checked_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_checked_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x0, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x1, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x2, x2, x6 | 
 | ; CHECK-NEXT:    sbcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w8, lo | 
 | ; CHECK-NEXT:    eor w4, w8, #0x1 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.usub.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = xor i1 %3, true | 
 |   %5 = zext i1 %4 to i8 | 
 |   %6 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %7 = insertvalue { i256, i8 } %6, i8 %5, 1 | 
 |   ret { i256, i8 } %7 | 
 | } | 
 |  | 
 | define { i256, i8 } @u256_overflowing_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_overflowing_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x0, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x1, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x2, x2, x6 | 
 | ; CHECK-NEXT:    sbcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w4, lo | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.usub.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = zext i1 %3 to i8 | 
 |   %5 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %6 = insertvalue { i256, i8 } %5, i8 %4, 1 | 
 |   ret { i256, i8 } %6 | 
 | } | 
 |  | 
 | define i256 @u256_saturating_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: u256_saturating_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x8, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x9, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x10, x2, x6 | 
 | ; CHECK-NEXT:    sbcs x11, x3, x7 | 
 | ; CHECK-NEXT:    csel x0, xzr, x8, lo | 
 | ; CHECK-NEXT:    csel x1, xzr, x9, lo | 
 | ; CHECK-NEXT:    csel x2, xzr, x10, lo | 
 | ; CHECK-NEXT:    csel x3, xzr, x11, lo | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call i256 @llvm.usub.sat.i256(i256 %x, i256 %y) | 
 |   ret i256 %1 | 
 | } | 
 |  | 
 | define i256 @i256_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x0, x0, x4 | 
 | ; CHECK-NEXT:    adcs x1, x1, x5 | 
 | ; CHECK-NEXT:    adcs x2, x2, x6 | 
 | ; CHECK-NEXT:    adc x3, x3, x7 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = add i256 %x, %y | 
 |   ret i256 %1 | 
 | } | 
 |  | 
 | define { i256, i8 } @i256_checked_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_checked_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x0, x0, x4 | 
 | ; CHECK-NEXT:    adcs x1, x1, x5 | 
 | ; CHECK-NEXT:    adcs x2, x2, x6 | 
 | ; CHECK-NEXT:    adcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w8, vs | 
 | ; CHECK-NEXT:    eor w4, w8, #0x1 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.sadd.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = xor i1 %3, true | 
 |   %5 = zext i1 %4 to i8 | 
 |   %6 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %7 = insertvalue { i256, i8 } %6, i8 %5, 1 | 
 |   ret { i256, i8 } %7 | 
 | } | 
 |  | 
 | define { i256, i8 } @i256_overflowing_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_overflowing_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x0, x0, x4 | 
 | ; CHECK-NEXT:    adcs x1, x1, x5 | 
 | ; CHECK-NEXT:    adcs x2, x2, x6 | 
 | ; CHECK-NEXT:    adcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w4, vs | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.sadd.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = zext i1 %3 to i8 | 
 |   %5 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %6 = insertvalue { i256, i8 } %5, i8 %4, 1 | 
 |   ret { i256, i8 } %6 | 
 | } | 
 |  | 
 | define i256 @i256_saturating_add(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_saturating_add: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    adds x8, x0, x4 | 
 | ; CHECK-NEXT:    adcs x9, x1, x5 | 
 | ; CHECK-NEXT:    adcs x10, x2, x6 | 
 | ; CHECK-NEXT:    adcs x11, x3, x7 | 
 | ; CHECK-NEXT:    asr x12, x11, #63 | 
 | ; CHECK-NEXT:    csel x0, x12, x8, vs | 
 | ; CHECK-NEXT:    eor x8, x12, #0x8000000000000000 | 
 | ; CHECK-NEXT:    csel x1, x12, x9, vs | 
 | ; CHECK-NEXT:    csel x2, x12, x10, vs | 
 | ; CHECK-NEXT:    csel x3, x8, x11, vs | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call i256 @llvm.sadd.sat.i256(i256 %x, i256 %y) | 
 |   ret i256 %1 | 
 | } | 
 |  | 
 | define i256 @i256_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x0, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x1, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x2, x2, x6 | 
 | ; CHECK-NEXT:    sbc x3, x3, x7 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = sub i256 %x, %y | 
 |   ret i256 %1 | 
 | } | 
 |  | 
 | define { i256, i8 } @i256_checked_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_checked_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x0, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x1, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x2, x2, x6 | 
 | ; CHECK-NEXT:    sbcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w8, vs | 
 | ; CHECK-NEXT:    eor w4, w8, #0x1 | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.ssub.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = xor i1 %3, true | 
 |   %5 = zext i1 %4 to i8 | 
 |   %6 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %7 = insertvalue { i256, i8 } %6, i8 %5, 1 | 
 |   ret { i256, i8 } %7 | 
 | } | 
 |  | 
 | define { i256, i8 } @i256_overflowing_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_overflowing_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x0, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x1, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x2, x2, x6 | 
 | ; CHECK-NEXT:    sbcs x3, x3, x7 | 
 | ; CHECK-NEXT:    cset w4, vs | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call { i256, i1 } @llvm.ssub.with.overflow.i256(i256 %x, i256 %y) | 
 |   %2 = extractvalue { i256, i1 } %1, 0 | 
 |   %3 = extractvalue { i256, i1 } %1, 1 | 
 |   %4 = zext i1 %3 to i8 | 
 |   %5 = insertvalue { i256, i8 } undef, i256 %2, 0 | 
 |   %6 = insertvalue { i256, i8 } %5, i8 %4, 1 | 
 |   ret { i256, i8 } %6 | 
 | } | 
 |  | 
 | define i256 @i256_saturating_sub(i256 %x, i256 %y) { | 
 | ; CHECK-LABEL: i256_saturating_sub: | 
 | ; CHECK:       // %bb.0: | 
 | ; CHECK-NEXT:    subs x8, x0, x4 | 
 | ; CHECK-NEXT:    sbcs x9, x1, x5 | 
 | ; CHECK-NEXT:    sbcs x10, x2, x6 | 
 | ; CHECK-NEXT:    sbcs x11, x3, x7 | 
 | ; CHECK-NEXT:    asr x12, x11, #63 | 
 | ; CHECK-NEXT:    csel x0, x12, x8, vs | 
 | ; CHECK-NEXT:    eor x8, x12, #0x8000000000000000 | 
 | ; CHECK-NEXT:    csel x1, x12, x9, vs | 
 | ; CHECK-NEXT:    csel x2, x12, x10, vs | 
 | ; CHECK-NEXT:    csel x3, x8, x11, vs | 
 | ; CHECK-NEXT:    ret | 
 |   %1 = tail call i256 @llvm.ssub.sat.i256(i256 %x, i256 %y) | 
 |   ret i256 %1 | 
 | } |