| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -mtriple=aarch64-none-eabi -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD | |
| ; RUN: llc -mtriple=aarch64-none-eabi -global-isel -global-isel-abort=2 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI | |
| ; CHECK-GI: warning: Instruction selection used fallback path for sadd_v32i8 | |
| ; CHECK-GI-NEXT: warning: Instruction selection used fallback path for ssub_v32i8 | |
| define <2 x i8> @uadd_v2i8(<2 x i8> %a, <2 x i8> %b) { | |
| ; CHECK-SD-LABEL: uadd_v2i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: movi d2, #0x0000ff000000ff | |
| ; CHECK-SD-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: and v2.8b, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: add v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: fmov d2, d1 | |
| ; CHECK-SD-NEXT: bic v2.2s, #1, lsl #8 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v2i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: add v2.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mov w9, v1.s[1] | |
| ; CHECK-GI-NEXT: mov w8, v2.s[1] | |
| ; CHECK-GI-NEXT: mov v3.16b, v2.16b | |
| ; CHECK-GI-NEXT: mov v1.b[1], w9 | |
| ; CHECK-GI-NEXT: mov v3.b[1], w8 | |
| ; CHECK-GI-NEXT: cmhi v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: umov w8, v1.b[0] | |
| ; CHECK-GI-NEXT: umov w9, v1.b[1] | |
| ; CHECK-GI-NEXT: fmov s1, w8 | |
| ; CHECK-GI-NEXT: mov v1.s[1], w9 | |
| ; CHECK-GI-NEXT: shl v1.2s, v1.2s, #31 | |
| ; CHECK-GI-NEXT: cmlt v1.2s, v1.2s, #0 | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i8>, <2 x i1>} @llvm.uadd.with.overflow(<2 x i8> %a, <2 x i8> %b) | |
| %e0 = extractvalue {<2 x i8>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i8>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i8> %e0, <2 x i8> %a | |
| ret <2 x i8> %r | |
| } | |
| define <2 x i8> @sadd_v2i8(<2 x i8> %a, <2 x i8> %b) { | |
| ; CHECK-SD-LABEL: sadd_v2i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v2.2s, v0.2s, #24 | |
| ; CHECK-SD-NEXT: shl v1.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #24 | |
| ; CHECK-SD-NEXT: ssra v2.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: shl v1.2s, v2.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v1.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: cmeq v1.2s, v1.2s, v2.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v2i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: add v3.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mov w9, v0.s[1] | |
| ; CHECK-GI-NEXT: mov w10, v1.s[1] | |
| ; CHECK-GI-NEXT: mov v5.16b, v0.16b | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: mov w8, v3.s[1] | |
| ; CHECK-GI-NEXT: mov v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: mov v5.b[1], w9 | |
| ; CHECK-GI-NEXT: mov v1.b[1], w10 | |
| ; CHECK-GI-NEXT: mov v4.b[1], w8 | |
| ; CHECK-GI-NEXT: cmgt v1.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: cmgt v4.8b, v5.8b, v4.8b | |
| ; CHECK-GI-NEXT: umov w8, v1.b[0] | |
| ; CHECK-GI-NEXT: umov w10, v1.b[1] | |
| ; CHECK-GI-NEXT: umov w9, v4.b[0] | |
| ; CHECK-GI-NEXT: umov w11, v4.b[1] | |
| ; CHECK-GI-NEXT: fmov s1, w8 | |
| ; CHECK-GI-NEXT: fmov s2, w9 | |
| ; CHECK-GI-NEXT: mov v1.s[1], w10 | |
| ; CHECK-GI-NEXT: mov v2.s[1], w11 | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: shl v1.2s, v1.2s, #31 | |
| ; CHECK-GI-NEXT: cmlt v1.2s, v1.2s, #0 | |
| ; CHECK-GI-NEXT: bit v0.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i8>, <2 x i1>} @llvm.sadd.with.overflow(<2 x i8> %a, <2 x i8> %b) | |
| %e0 = extractvalue {<2 x i8>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i8>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i8> %e0, <2 x i8> %a | |
| ret <2 x i8> %r | |
| } | |
| define <2 x i8> @usub_v2i8(<2 x i8> %a, <2 x i8> %b) { | |
| ; CHECK-SD-LABEL: usub_v2i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: movi d2, #0x0000ff000000ff | |
| ; CHECK-SD-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: and v3.8b, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: sub v1.2s, v3.2s, v1.2s | |
| ; CHECK-SD-NEXT: and v2.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v2i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: mov w8, v0.s[1] | |
| ; CHECK-GI-NEXT: mov w9, v1.s[1] | |
| ; CHECK-GI-NEXT: mov v2.16b, v0.16b | |
| ; CHECK-GI-NEXT: sub v3.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mov v2.b[1], w8 | |
| ; CHECK-GI-NEXT: mov v1.b[1], w9 | |
| ; CHECK-GI-NEXT: cmhi v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: umov w8, v1.b[0] | |
| ; CHECK-GI-NEXT: umov w9, v1.b[1] | |
| ; CHECK-GI-NEXT: fmov s1, w8 | |
| ; CHECK-GI-NEXT: mov v1.s[1], w9 | |
| ; CHECK-GI-NEXT: shl v1.2s, v1.2s, #31 | |
| ; CHECK-GI-NEXT: cmlt v1.2s, v1.2s, #0 | |
| ; CHECK-GI-NEXT: bit v0.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i8>, <2 x i1>} @llvm.usub.with.overflow(<2 x i8> %a, <2 x i8> %b) | |
| %e0 = extractvalue {<2 x i8>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i8>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i8> %e0, <2 x i8> %a | |
| ret <2 x i8> %r | |
| } | |
| define <2 x i8> @ssub_v2i8(<2 x i8> %a, <2 x i8> %b) { | |
| ; CHECK-SD-LABEL: ssub_v2i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v1.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: shl v2.2s, v0.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v1.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #24 | |
| ; CHECK-SD-NEXT: sub v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: shl v2.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #24 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v2i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: sub v3.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mov w8, v0.s[1] | |
| ; CHECK-GI-NEXT: mov w9, v1.s[1] | |
| ; CHECK-GI-NEXT: mov v4.16b, v0.16b | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: mov w10, v3.s[1] | |
| ; CHECK-GI-NEXT: mov v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: mov v4.b[1], w8 | |
| ; CHECK-GI-NEXT: mov v1.b[1], w9 | |
| ; CHECK-GI-NEXT: mov v5.b[1], w10 | |
| ; CHECK-GI-NEXT: cmgt v1.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: cmgt v2.8b, v2.8b, v5.8b | |
| ; CHECK-GI-NEXT: umov w8, v1.b[0] | |
| ; CHECK-GI-NEXT: umov w10, v1.b[1] | |
| ; CHECK-GI-NEXT: umov w9, v2.b[0] | |
| ; CHECK-GI-NEXT: umov w11, v2.b[1] | |
| ; CHECK-GI-NEXT: fmov s1, w8 | |
| ; CHECK-GI-NEXT: fmov s2, w9 | |
| ; CHECK-GI-NEXT: mov v1.s[1], w10 | |
| ; CHECK-GI-NEXT: mov v2.s[1], w11 | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: shl v1.2s, v1.2s, #31 | |
| ; CHECK-GI-NEXT: cmlt v1.2s, v1.2s, #0 | |
| ; CHECK-GI-NEXT: bit v0.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i8>, <2 x i1>} @llvm.ssub.with.overflow(<2 x i8> %a, <2 x i8> %b) | |
| %e0 = extractvalue {<2 x i8>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i8>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i8> %e0, <2 x i8> %a | |
| ret <2 x i8> %r | |
| } | |
| define <2 x i8> @umul_v2i8(<2 x i8> %a, <2 x i8> %b) { | |
| ; CHECK-SD-LABEL: umul_v2i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: movi d2, #0x0000ff000000ff | |
| ; CHECK-SD-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: and v2.8b, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: mul v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: ushr v2.2s, v1.2s, #8 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v2i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi d2, #0x0000ff000000ff | |
| ; CHECK-GI-NEXT: and v3.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: mul v1.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mul v2.2s, v3.2s, v2.2s | |
| ; CHECK-GI-NEXT: movi v3.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: uzp1 v2.4h, v2.4h, v0.4h | |
| ; CHECK-GI-NEXT: ushr v2.4h, v2.4h, #8 | |
| ; CHECK-GI-NEXT: uzp1 v2.8b, v2.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmeq v2.8b, v2.8b, v3.8b | |
| ; CHECK-GI-NEXT: mvn v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: umov w8, v2.b[0] | |
| ; CHECK-GI-NEXT: umov w9, v2.b[1] | |
| ; CHECK-GI-NEXT: fmov s2, w8 | |
| ; CHECK-GI-NEXT: mov v2.s[1], w9 | |
| ; CHECK-GI-NEXT: shl v2.2s, v2.2s, #31 | |
| ; CHECK-GI-NEXT: cmlt v2.2s, v2.2s, #0 | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i8>, <2 x i1>} @llvm.umul.with.overflow(<2 x i8> %a, <2 x i8> %b) | |
| %e0 = extractvalue {<2 x i8>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i8>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i8> %e0, <2 x i8> %a | |
| ret <2 x i8> %r | |
| } | |
| define <2 x i8> @smul_v2i8(<2 x i8> %a, <2 x i8> %b) { | |
| ; CHECK-SD-LABEL: smul_v2i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v1.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: shl v2.2s, v0.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v1.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #24 | |
| ; CHECK-SD-NEXT: mul v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: shl v2.2s, v1.2s, #24 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #24 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v2i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: shl v3.2s, v0.2s, #24 | |
| ; CHECK-GI-NEXT: shl v4.2s, v1.2s, #24 | |
| ; CHECK-GI-NEXT: mul v1.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: movi v2.8b, #15 | |
| ; CHECK-GI-NEXT: sshr v3.2s, v3.2s, #24 | |
| ; CHECK-GI-NEXT: sshr v4.2s, v4.2s, #24 | |
| ; CHECK-GI-NEXT: mov w8, v1.s[1] | |
| ; CHECK-GI-NEXT: neg v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: mul v3.2s, v3.2s, v4.2s | |
| ; CHECK-GI-NEXT: mov v4.16b, v1.16b | |
| ; CHECK-GI-NEXT: mov v4.b[1], w8 | |
| ; CHECK-GI-NEXT: uzp1 v3.4h, v3.4h, v0.4h | |
| ; CHECK-GI-NEXT: sshl v2.8b, v4.8b, v2.8b | |
| ; CHECK-GI-NEXT: sshr v3.4h, v3.4h, #8 | |
| ; CHECK-GI-NEXT: uzp1 v3.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmeq v2.8b, v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: mvn v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: umov w8, v2.b[0] | |
| ; CHECK-GI-NEXT: umov w9, v2.b[1] | |
| ; CHECK-GI-NEXT: fmov s2, w8 | |
| ; CHECK-GI-NEXT: mov v2.s[1], w9 | |
| ; CHECK-GI-NEXT: shl v2.2s, v2.2s, #31 | |
| ; CHECK-GI-NEXT: cmlt v2.2s, v2.2s, #0 | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i8>, <2 x i1>} @llvm.smul.with.overflow(<2 x i8> %a, <2 x i8> %b) | |
| %e0 = extractvalue {<2 x i8>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i8>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i8> %e0, <2 x i8> %a | |
| ret <2 x i8> %r | |
| } | |
| define <3 x i8> @uadd_v3i8(<3 x i8> %a, <3 x i8> %b) { | |
| ; CHECK-SD-LABEL: uadd_v3i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov s0, w0 | |
| ; CHECK-SD-NEXT: fmov s1, w3 | |
| ; CHECK-SD-NEXT: mov v0.h[1], w1 | |
| ; CHECK-SD-NEXT: mov v1.h[1], w4 | |
| ; CHECK-SD-NEXT: mov v0.h[2], w2 | |
| ; CHECK-SD-NEXT: mov v1.h[2], w5 | |
| ; CHECK-SD-NEXT: fmov d2, d0 | |
| ; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: add v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: fmov d2, d1 | |
| ; CHECK-SD-NEXT: bic v2.4h, #1, lsl #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: umov w0, v0.h[0] | |
| ; CHECK-SD-NEXT: umov w1, v0.h[1] | |
| ; CHECK-SD-NEXT: umov w2, v0.h[2] | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v3i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: fmov s0, w3 | |
| ; CHECK-GI-NEXT: fmov s1, w0 | |
| ; CHECK-GI-NEXT: mov v2.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v1.h[1], w1 | |
| ; CHECK-GI-NEXT: mov v0.b[1], w4 | |
| ; CHECK-GI-NEXT: mov v2.h[1], w4 | |
| ; CHECK-GI-NEXT: mov v1.h[2], w2 | |
| ; CHECK-GI-NEXT: mov v2.h[2], w5 | |
| ; CHECK-GI-NEXT: add v2.4h, v1.4h, v2.4h | |
| ; CHECK-GI-NEXT: uzp1 v3.8b, v2.8b, v0.8b | |
| ; CHECK-GI-NEXT: mov v0.b[2], w5 | |
| ; CHECK-GI-NEXT: cmhi v0.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: movi d3, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: zip1 v0.8b, v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: shl v0.4h, v0.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v0.4h, v0.4h, #0 | |
| ; CHECK-GI-NEXT: eor v3.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v2.8b, v0.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: umov w0, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w1, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w2, v0.h[2] | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i8>, <3 x i1>} @llvm.uadd.with.overflow(<3 x i8> %a, <3 x i8> %b) | |
| %e0 = extractvalue {<3 x i8>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i8>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i8> %e0, <3 x i8> %a | |
| ret <3 x i8> %r | |
| } | |
| define <3 x i8> @sadd_v3i8(<3 x i8> %a, <3 x i8> %b) { | |
| ; CHECK-SD-LABEL: sadd_v3i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov s0, w0 | |
| ; CHECK-SD-NEXT: fmov s1, w3 | |
| ; CHECK-SD-NEXT: mov v0.h[1], w1 | |
| ; CHECK-SD-NEXT: mov v1.h[1], w4 | |
| ; CHECK-SD-NEXT: mov v0.h[2], w2 | |
| ; CHECK-SD-NEXT: mov v1.h[2], w5 | |
| ; CHECK-SD-NEXT: shl v2.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: shl v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: ssra v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: shl v1.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v1.4h, v1.4h, v2.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: umov w0, v0.h[0] | |
| ; CHECK-SD-NEXT: umov w1, v0.h[1] | |
| ; CHECK-SD-NEXT: umov w2, v0.h[2] | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v3i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: fmov s1, w0 | |
| ; CHECK-GI-NEXT: fmov s2, w3 | |
| ; CHECK-GI-NEXT: movi v5.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: mov v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: mov v3.16b, v2.16b | |
| ; CHECK-GI-NEXT: mov v1.b[1], w1 | |
| ; CHECK-GI-NEXT: mov v2.b[1], w4 | |
| ; CHECK-GI-NEXT: mov v0.h[1], w1 | |
| ; CHECK-GI-NEXT: mov v3.h[1], w4 | |
| ; CHECK-GI-NEXT: mov v1.b[2], w2 | |
| ; CHECK-GI-NEXT: mov v2.b[2], w5 | |
| ; CHECK-GI-NEXT: mov v0.h[2], w2 | |
| ; CHECK-GI-NEXT: mov v3.h[2], w5 | |
| ; CHECK-GI-NEXT: cmgt v2.8b, v5.8b, v2.8b | |
| ; CHECK-GI-NEXT: add v3.4h, v0.4h, v3.4h | |
| ; CHECK-GI-NEXT: mov b5, v2.b[1] | |
| ; CHECK-GI-NEXT: mov b7, v2.b[2] | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: fmov w8, s5 | |
| ; CHECK-GI-NEXT: cmgt v1.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: mov v2.h[1], w8 | |
| ; CHECK-GI-NEXT: fmov w8, s7 | |
| ; CHECK-GI-NEXT: mov b4, v1.b[1] | |
| ; CHECK-GI-NEXT: mov b6, v1.b[2] | |
| ; CHECK-GI-NEXT: mov v2.h[2], w8 | |
| ; CHECK-GI-NEXT: fmov w9, s4 | |
| ; CHECK-GI-NEXT: mov v1.h[1], w9 | |
| ; CHECK-GI-NEXT: fmov w9, s6 | |
| ; CHECK-GI-NEXT: mov v1.h[2], w9 | |
| ; CHECK-GI-NEXT: eor v1.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: movi d2, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: shl v1.4h, v1.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v1.4h, v1.4h, #0 | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: umov w0, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w1, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w2, v0.h[2] | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i8>, <3 x i1>} @llvm.sadd.with.overflow(<3 x i8> %a, <3 x i8> %b) | |
| %e0 = extractvalue {<3 x i8>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i8>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i8> %e0, <3 x i8> %a | |
| ret <3 x i8> %r | |
| } | |
| define <3 x i8> @usub_v3i8(<3 x i8> %a, <3 x i8> %b) { | |
| ; CHECK-SD-LABEL: usub_v3i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov s0, w0 | |
| ; CHECK-SD-NEXT: fmov s1, w3 | |
| ; CHECK-SD-NEXT: mov v0.h[1], w1 | |
| ; CHECK-SD-NEXT: mov v1.h[1], w4 | |
| ; CHECK-SD-NEXT: mov v0.h[2], w2 | |
| ; CHECK-SD-NEXT: mov v1.h[2], w5 | |
| ; CHECK-SD-NEXT: fmov d2, d0 | |
| ; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: sub v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: fmov d2, d1 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: umov w0, v0.h[0] | |
| ; CHECK-SD-NEXT: umov w1, v0.h[1] | |
| ; CHECK-SD-NEXT: umov w2, v0.h[2] | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v3i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: fmov s0, w0 | |
| ; CHECK-GI-NEXT: fmov s1, w3 | |
| ; CHECK-GI-NEXT: mov v2.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v3.16b, v1.16b | |
| ; CHECK-GI-NEXT: mov v0.b[1], w1 | |
| ; CHECK-GI-NEXT: mov v1.b[1], w4 | |
| ; CHECK-GI-NEXT: mov v2.h[1], w1 | |
| ; CHECK-GI-NEXT: mov v3.h[1], w4 | |
| ; CHECK-GI-NEXT: mov v0.b[2], w2 | |
| ; CHECK-GI-NEXT: mov v1.b[2], w5 | |
| ; CHECK-GI-NEXT: mov v2.h[2], w2 | |
| ; CHECK-GI-NEXT: mov v3.h[2], w5 | |
| ; CHECK-GI-NEXT: cmhi v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: movi d1, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: sub v3.4h, v2.4h, v3.4h | |
| ; CHECK-GI-NEXT: zip1 v0.8b, v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: shl v0.4h, v0.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v0.4h, v0.4h, #0 | |
| ; CHECK-GI-NEXT: eor v1.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: umov w0, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w1, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w2, v0.h[2] | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i8>, <3 x i1>} @llvm.usub.with.overflow(<3 x i8> %a, <3 x i8> %b) | |
| %e0 = extractvalue {<3 x i8>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i8>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i8> %e0, <3 x i8> %a | |
| ret <3 x i8> %r | |
| } | |
| define <3 x i8> @ssub_v3i8(<3 x i8> %a, <3 x i8> %b) { | |
| ; CHECK-SD-LABEL: ssub_v3i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov s0, w3 | |
| ; CHECK-SD-NEXT: fmov s1, w0 | |
| ; CHECK-SD-NEXT: mov v0.h[1], w4 | |
| ; CHECK-SD-NEXT: mov v1.h[1], w1 | |
| ; CHECK-SD-NEXT: mov v0.h[2], w5 | |
| ; CHECK-SD-NEXT: mov v1.h[2], w2 | |
| ; CHECK-SD-NEXT: shl v0.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: shl v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v0.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: sub v0.4h, v2.4h, v0.4h | |
| ; CHECK-SD-NEXT: shl v2.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v0.4h | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: umov w0, v0.h[0] | |
| ; CHECK-SD-NEXT: umov w1, v0.h[1] | |
| ; CHECK-SD-NEXT: umov w2, v0.h[2] | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v3i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: fmov s1, w0 | |
| ; CHECK-GI-NEXT: fmov s2, w3 | |
| ; CHECK-GI-NEXT: movi v5.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: mov v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: mov v3.16b, v2.16b | |
| ; CHECK-GI-NEXT: mov v1.b[1], w1 | |
| ; CHECK-GI-NEXT: mov v2.b[1], w4 | |
| ; CHECK-GI-NEXT: mov v0.h[1], w1 | |
| ; CHECK-GI-NEXT: mov v3.h[1], w4 | |
| ; CHECK-GI-NEXT: mov v1.b[2], w2 | |
| ; CHECK-GI-NEXT: mov v2.b[2], w5 | |
| ; CHECK-GI-NEXT: mov v0.h[2], w2 | |
| ; CHECK-GI-NEXT: mov v3.h[2], w5 | |
| ; CHECK-GI-NEXT: cmgt v1.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: sub v3.4h, v0.4h, v3.4h | |
| ; CHECK-GI-NEXT: mov b6, v1.b[2] | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmgt v2.8b, v5.8b, v4.8b | |
| ; CHECK-GI-NEXT: mov b4, v1.b[1] | |
| ; CHECK-GI-NEXT: mov b5, v2.b[1] | |
| ; CHECK-GI-NEXT: mov b7, v2.b[2] | |
| ; CHECK-GI-NEXT: fmov w8, s4 | |
| ; CHECK-GI-NEXT: fmov w9, s5 | |
| ; CHECK-GI-NEXT: mov v1.h[1], w8 | |
| ; CHECK-GI-NEXT: fmov w8, s6 | |
| ; CHECK-GI-NEXT: mov v2.h[1], w9 | |
| ; CHECK-GI-NEXT: fmov w9, s7 | |
| ; CHECK-GI-NEXT: mov v1.h[2], w8 | |
| ; CHECK-GI-NEXT: mov v2.h[2], w9 | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: movi d2, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: shl v1.4h, v1.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v1.4h, v1.4h, #0 | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: umov w0, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w1, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w2, v0.h[2] | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i8>, <3 x i1>} @llvm.ssub.with.overflow(<3 x i8> %a, <3 x i8> %b) | |
| %e0 = extractvalue {<3 x i8>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i8>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i8> %e0, <3 x i8> %a | |
| ret <3 x i8> %r | |
| } | |
| define <3 x i8> @umul_v3i8(<3 x i8> %a, <3 x i8> %b) { | |
| ; CHECK-SD-LABEL: umul_v3i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov s0, w0 | |
| ; CHECK-SD-NEXT: fmov s1, w3 | |
| ; CHECK-SD-NEXT: mov v0.h[1], w1 | |
| ; CHECK-SD-NEXT: mov v1.h[1], w4 | |
| ; CHECK-SD-NEXT: mov v0.h[2], w2 | |
| ; CHECK-SD-NEXT: mov v1.h[2], w5 | |
| ; CHECK-SD-NEXT: fmov d2, d0 | |
| ; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: mul v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: ushr v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: umov w0, v0.h[0] | |
| ; CHECK-SD-NEXT: umov w1, v0.h[1] | |
| ; CHECK-SD-NEXT: umov w2, v0.h[2] | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v3i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: and w8, w0, #0xff | |
| ; CHECK-GI-NEXT: and w10, w3, #0xff | |
| ; CHECK-GI-NEXT: and w9, w1, #0xff | |
| ; CHECK-GI-NEXT: fmov s0, w8 | |
| ; CHECK-GI-NEXT: fmov s1, w10 | |
| ; CHECK-GI-NEXT: and w8, w4, #0xff | |
| ; CHECK-GI-NEXT: fmov s2, w3 | |
| ; CHECK-GI-NEXT: movi d3, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: mov v0.h[1], w9 | |
| ; CHECK-GI-NEXT: mov v1.h[1], w8 | |
| ; CHECK-GI-NEXT: and w8, w2, #0xff | |
| ; CHECK-GI-NEXT: and w9, w5, #0xff | |
| ; CHECK-GI-NEXT: mov v2.h[1], w4 | |
| ; CHECK-GI-NEXT: mov v0.h[2], w8 | |
| ; CHECK-GI-NEXT: mov v1.h[2], w9 | |
| ; CHECK-GI-NEXT: mov v2.h[2], w5 | |
| ; CHECK-GI-NEXT: mul v0.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: movi v1.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: ushr v0.4h, v0.4h, #8 | |
| ; CHECK-GI-NEXT: uzp1 v0.8b, v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmeq v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: fmov s1, w0 | |
| ; CHECK-GI-NEXT: mvn v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: mov v1.h[1], w1 | |
| ; CHECK-GI-NEXT: zip1 v0.8b, v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: mov v1.h[2], w2 | |
| ; CHECK-GI-NEXT: shl v0.4h, v0.4h, #15 | |
| ; CHECK-GI-NEXT: mul v2.4h, v1.4h, v2.4h | |
| ; CHECK-GI-NEXT: cmlt v0.4h, v0.4h, #0 | |
| ; CHECK-GI-NEXT: eor v3.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v2.8b, v0.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: umov w0, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w1, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w2, v0.h[2] | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i8>, <3 x i1>} @llvm.umul.with.overflow(<3 x i8> %a, <3 x i8> %b) | |
| %e0 = extractvalue {<3 x i8>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i8>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i8> %e0, <3 x i8> %a | |
| ret <3 x i8> %r | |
| } | |
| define <3 x i8> @smul_v3i8(<3 x i8> %a, <3 x i8> %b) { | |
| ; CHECK-SD-LABEL: smul_v3i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov s0, w3 | |
| ; CHECK-SD-NEXT: fmov s1, w0 | |
| ; CHECK-SD-NEXT: mov v0.h[1], w4 | |
| ; CHECK-SD-NEXT: mov v1.h[1], w1 | |
| ; CHECK-SD-NEXT: mov v0.h[2], w5 | |
| ; CHECK-SD-NEXT: mov v1.h[2], w2 | |
| ; CHECK-SD-NEXT: shl v0.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: shl v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v0.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: mul v0.4h, v2.4h, v0.4h | |
| ; CHECK-SD-NEXT: shl v2.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v0.4h | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: umov w0, v0.h[0] | |
| ; CHECK-SD-NEXT: umov w1, v0.h[1] | |
| ; CHECK-SD-NEXT: umov w2, v0.h[2] | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v3i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: lsl w8, w0, #8 | |
| ; CHECK-GI-NEXT: lsl w10, w3, #8 | |
| ; CHECK-GI-NEXT: lsl w9, w1, #8 | |
| ; CHECK-GI-NEXT: lsl w11, w4, #8 | |
| ; CHECK-GI-NEXT: fmov s0, w0 | |
| ; CHECK-GI-NEXT: fmov s1, w3 | |
| ; CHECK-GI-NEXT: sbfx w8, w8, #8, #8 | |
| ; CHECK-GI-NEXT: sbfx w10, w10, #8, #8 | |
| ; CHECK-GI-NEXT: sbfx w9, w9, #8, #8 | |
| ; CHECK-GI-NEXT: sbfx w11, w11, #8, #8 | |
| ; CHECK-GI-NEXT: lsl w12, w2, #8 | |
| ; CHECK-GI-NEXT: fmov s2, w8 | |
| ; CHECK-GI-NEXT: fmov s3, w10 | |
| ; CHECK-GI-NEXT: lsl w8, w5, #8 | |
| ; CHECK-GI-NEXT: mov v0.h[1], w1 | |
| ; CHECK-GI-NEXT: mov v1.h[1], w4 | |
| ; CHECK-GI-NEXT: sbfx w8, w8, #8, #8 | |
| ; CHECK-GI-NEXT: mov v2.h[1], w9 | |
| ; CHECK-GI-NEXT: mov v3.h[1], w11 | |
| ; CHECK-GI-NEXT: sbfx w9, w12, #8, #8 | |
| ; CHECK-GI-NEXT: mov v0.h[2], w2 | |
| ; CHECK-GI-NEXT: mov v1.h[2], w5 | |
| ; CHECK-GI-NEXT: mov v2.h[2], w9 | |
| ; CHECK-GI-NEXT: mov v3.h[2], w8 | |
| ; CHECK-GI-NEXT: mul v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: mul v2.4h, v2.4h, v3.4h | |
| ; CHECK-GI-NEXT: movi v3.8b, #23 | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-GI-NEXT: neg v3.8b, v3.8b | |
| ; CHECK-GI-NEXT: uzp1 v2.8b, v2.8b, v0.8b | |
| ; CHECK-GI-NEXT: sshl v3.8b, v4.8b, v3.8b | |
| ; CHECK-GI-NEXT: cmeq v2.8b, v2.8b, v3.8b | |
| ; CHECK-GI-NEXT: movi d3, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: mvn v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: zip1 v2.8b, v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: shl v2.4h, v2.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v2.4h, v2.4h, #0 | |
| ; CHECK-GI-NEXT: eor v3.8b, v2.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: umov w0, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w1, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w2, v0.h[2] | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i8>, <3 x i1>} @llvm.smul.with.overflow(<3 x i8> %a, <3 x i8> %b) | |
| %e0 = extractvalue {<3 x i8>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i8>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i8> %e0, <3 x i8> %a | |
| ret <3 x i8> %r | |
| } | |
| define <4 x i8> @uadd_v4i8(<4 x i8> %a, <4 x i8> %b) { | |
| ; CHECK-SD-LABEL: uadd_v4i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov d2, d0 | |
| ; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: add v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: fmov d2, d1 | |
| ; CHECK-SD-NEXT: bic v2.4h, #1, lsl #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v4i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v3.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: movi d2, #0xff00ff00ff00ff | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmhi v1.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: zip1 v1.8b, v1.8b, v1.8b | |
| ; CHECK-GI-NEXT: shl v1.4h, v1.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v1.4h, v1.4h, #0 | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i8>, <4 x i1>} @llvm.uadd.with.overflow(<4 x i8> %a, <4 x i8> %b) | |
| %e0 = extractvalue {<4 x i8>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i8>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i8> %e0, <4 x i8> %a | |
| ret <4 x i8> %r | |
| } | |
| define <4 x i8> @sadd_v4i8(<4 x i8> %a, <4 x i8> %b) { | |
| ; CHECK-SD-LABEL: sadd_v4i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v2.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: shl v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: ssra v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: shl v1.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v1.4h, v1.4h, v2.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v4i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v3.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: uzp1 v5.8b, v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmgt v1.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: cmgt v4.8b, v5.8b, v4.8b | |
| ; CHECK-GI-NEXT: zip1 v1.8b, v1.8b, v1.8b | |
| ; CHECK-GI-NEXT: zip1 v2.8b, v4.8b, v4.8b | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: movi d2, #0xff00ff00ff00ff | |
| ; CHECK-GI-NEXT: shl v1.4h, v1.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v1.4h, v1.4h, #0 | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i8>, <4 x i1>} @llvm.sadd.with.overflow(<4 x i8> %a, <4 x i8> %b) | |
| %e0 = extractvalue {<4 x i8>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i8>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i8> %e0, <4 x i8> %a | |
| ret <4 x i8> %r | |
| } | |
| define <4 x i8> @usub_v4i8(<4 x i8> %a, <4 x i8> %b) { | |
| ; CHECK-SD-LABEL: usub_v4i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov d2, d0 | |
| ; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: sub v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: fmov d2, d1 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v4i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: uzp1 v3.8b, v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: movi d2, #0xff00ff00ff00ff | |
| ; CHECK-GI-NEXT: sub v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: cmhi v3.8b, v4.8b, v3.8b | |
| ; CHECK-GI-NEXT: zip1 v3.8b, v3.8b, v3.8b | |
| ; CHECK-GI-NEXT: shl v3.4h, v3.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v3.4h, v3.4h, #0 | |
| ; CHECK-GI-NEXT: eor v2.8b, v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i8>, <4 x i1>} @llvm.usub.with.overflow(<4 x i8> %a, <4 x i8> %b) | |
| %e0 = extractvalue {<4 x i8>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i8>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i8> %e0, <4 x i8> %a | |
| ret <4 x i8> %r | |
| } | |
| define <4 x i8> @ssub_v4i8(<4 x i8> %a, <4 x i8> %b) { | |
| ; CHECK-SD-LABEL: ssub_v4i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: shl v2.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: sub v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: shl v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v4i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v3.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v0.8b, v0.8b | |
| ; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: uzp1 v5.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmgt v1.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: cmgt v2.8b, v2.8b, v5.8b | |
| ; CHECK-GI-NEXT: zip1 v1.8b, v1.8b, v1.8b | |
| ; CHECK-GI-NEXT: zip1 v2.8b, v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: movi d2, #0xff00ff00ff00ff | |
| ; CHECK-GI-NEXT: shl v1.4h, v1.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v1.4h, v1.4h, #0 | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i8>, <4 x i1>} @llvm.ssub.with.overflow(<4 x i8> %a, <4 x i8> %b) | |
| %e0 = extractvalue {<4 x i8>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i8>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i8> %e0, <4 x i8> %a | |
| ret <4 x i8> %r | |
| } | |
| define <4 x i8> @umul_v4i8(<4 x i8> %a, <4 x i8> %b) { | |
| ; CHECK-SD-LABEL: umul_v4i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: fmov d2, d0 | |
| ; CHECK-SD-NEXT: bic v1.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: bic v2.4h, #255, lsl #8 | |
| ; CHECK-SD-NEXT: mul v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: ushr v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v4i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi d2, #0xff00ff00ff00ff | |
| ; CHECK-GI-NEXT: and v3.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v4.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: mul v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: mul v3.4h, v3.4h, v4.4h | |
| ; CHECK-GI-NEXT: movi v4.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: ushr v3.4h, v3.4h, #8 | |
| ; CHECK-GI-NEXT: uzp1 v3.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmeq v3.8b, v3.8b, v4.8b | |
| ; CHECK-GI-NEXT: mvn v3.8b, v3.8b | |
| ; CHECK-GI-NEXT: zip1 v3.8b, v3.8b, v3.8b | |
| ; CHECK-GI-NEXT: shl v3.4h, v3.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v3.4h, v3.4h, #0 | |
| ; CHECK-GI-NEXT: eor v2.8b, v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i8>, <4 x i1>} @llvm.umul.with.overflow(<4 x i8> %a, <4 x i8> %b) | |
| %e0 = extractvalue {<4 x i8>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i8>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i8> %e0, <4 x i8> %a | |
| ret <4 x i8> %r | |
| } | |
| define <4 x i8> @smul_v4i8(<4 x i8> %a, <4 x i8> %b) { | |
| ; CHECK-SD-LABEL: smul_v4i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: shl v2.4h, v0.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v1.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: mul v1.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: shl v2.4h, v1.4h, #8 | |
| ; CHECK-SD-NEXT: sshr v2.4h, v2.4h, #8 | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, v1.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v4i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: shl v3.4h, v0.4h, #8 | |
| ; CHECK-GI-NEXT: shl v4.4h, v1.4h, #8 | |
| ; CHECK-GI-NEXT: mul v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: movi v2.8b, #31 | |
| ; CHECK-GI-NEXT: sshr v3.4h, v3.4h, #8 | |
| ; CHECK-GI-NEXT: sshr v4.4h, v4.4h, #8 | |
| ; CHECK-GI-NEXT: neg v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: mul v3.4h, v3.4h, v4.4h | |
| ; CHECK-GI-NEXT: uzp1 v4.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: sshr v3.4h, v3.4h, #8 | |
| ; CHECK-GI-NEXT: sshl v2.8b, v4.8b, v2.8b | |
| ; CHECK-GI-NEXT: uzp1 v3.8b, v3.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmeq v2.8b, v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: movi d3, #0xff00ff00ff00ff | |
| ; CHECK-GI-NEXT: mvn v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: zip1 v2.8b, v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: shl v2.4h, v2.4h, #15 | |
| ; CHECK-GI-NEXT: cmlt v2.4h, v2.4h, #0 | |
| ; CHECK-GI-NEXT: eor v3.8b, v2.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i8>, <4 x i1>} @llvm.smul.with.overflow(<4 x i8> %a, <4 x i8> %b) | |
| %e0 = extractvalue {<4 x i8>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i8>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i8> %e0, <4 x i8> %a | |
| ret <4 x i8> %r | |
| } | |
| define <8 x i8> @uadd_v8i8(<8 x i8> %a, <8 x i8> %b) { | |
| ; CHECK-SD-LABEL: uadd_v8i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.8b, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: cmhi v2.8b, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v8i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: cmhi v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i8>, <8 x i1>} @llvm.uadd.with.overflow(<8 x i8> %a, <8 x i8> %b) | |
| %e0 = extractvalue {<8 x i8>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i8>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i8> %e0, <8 x i8> %a | |
| ret <8 x i8> %r | |
| } | |
| define <8 x i8> @sadd_v8i8(<8 x i8> %a, <8 x i8> %b) { | |
| ; CHECK-SD-LABEL: sadd_v8i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.8b, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: add v1.8b, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: cmeq v2.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v8i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: cmlt v1.8b, v1.8b, #0 | |
| ; CHECK-GI-NEXT: cmgt v3.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i8>, <8 x i1>} @llvm.sadd.with.overflow(<8 x i8> %a, <8 x i8> %b) | |
| %e0 = extractvalue {<8 x i8>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i8>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i8> %e0, <8 x i8> %a | |
| ret <8 x i8> %r | |
| } | |
| define <8 x i8> @usub_v8i8(<8 x i8> %a, <8 x i8> %b) { | |
| ; CHECK-SD-LABEL: usub_v8i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.8b, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: cmhi v2.8b, v1.8b, v0.8b | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v8i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: cmhi v1.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i8>, <8 x i1>} @llvm.usub.with.overflow(<8 x i8> %a, <8 x i8> %b) | |
| %e0 = extractvalue {<8 x i8>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i8>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i8> %e0, <8 x i8> %a | |
| ret <8 x i8> %r | |
| } | |
| define <8 x i8> @ssub_v8i8(<8 x i8> %a, <8 x i8> %b) { | |
| ; CHECK-SD-LABEL: ssub_v8i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.8b, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: sub v1.8b, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: cmeq v2.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v8i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: cmgt v1.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: cmlt v3.8b, v2.8b, #0 | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i8>, <8 x i1>} @llvm.ssub.with.overflow(<8 x i8> %a, <8 x i8> %b) | |
| %e0 = extractvalue {<8 x i8>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i8>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i8> %e0, <8 x i8> %a | |
| ret <8 x i8> %r | |
| } | |
| define <8 x i8> @umul_v8i8(<8 x i8> %a, <8 x i8> %b) { | |
| ; CHECK-SD-LABEL: umul_v8i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull v1.8h, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: shrn v2.8b, v1.8h, #8 | |
| ; CHECK-SD-NEXT: xtn v1.8b, v1.8h | |
| ; CHECK-SD-NEXT: cmeq v2.8b, v2.8b, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v8i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull v2.8h, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: mul v1.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: shrn v2.8b, v2.8h, #8 | |
| ; CHECK-GI-NEXT: cmtst v2.8b, v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i8>, <8 x i1>} @llvm.umul.with.overflow(<8 x i8> %a, <8 x i8> %b) | |
| %e0 = extractvalue {<8 x i8>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i8>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i8> %e0, <8 x i8> %a | |
| ret <8 x i8> %r | |
| } | |
| define <8 x i8> @smul_v8i8(<8 x i8> %a, <8 x i8> %b) { | |
| ; CHECK-SD-LABEL: smul_v8i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull v1.8h, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: xtn v2.8b, v1.8h | |
| ; CHECK-SD-NEXT: shrn v1.8b, v1.8h, #8 | |
| ; CHECK-SD-NEXT: cmlt v3.8b, v2.8b, #0 | |
| ; CHECK-SD-NEXT: cmeq v1.8b, v1.8b, v3.8b | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v8i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.8b, #63 | |
| ; CHECK-GI-NEXT: smull v3.8h, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: mul v1.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: neg v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: shrn v3.8b, v3.8h, #8 | |
| ; CHECK-GI-NEXT: sshl v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: cmeq v2.8b, v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: mvn v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i8>, <8 x i1>} @llvm.smul.with.overflow(<8 x i8> %a, <8 x i8> %b) | |
| %e0 = extractvalue {<8 x i8>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i8>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i8> %e0, <8 x i8> %a | |
| ret <8 x i8> %r | |
| } | |
| define <16 x i8> @uadd_v16i8(<16 x i8> %a, <16 x i8> %b) { | |
| ; CHECK-SD-LABEL: uadd_v16i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: cmhi v2.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v16i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.16b, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: cmhi v1.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i8>, <16 x i1>} @llvm.uadd.with.overflow(<16 x i8> %a, <16 x i8> %b) | |
| %e0 = extractvalue {<16 x i8>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i8>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i8> %e0, <16 x i8> %a | |
| ret <16 x i8> %r | |
| } | |
| define <16 x i8> @sadd_v16i8(<16 x i8> %a, <16 x i8> %b) { | |
| ; CHECK-SD-LABEL: sadd_v16i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: add v1.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: cmeq v2.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v16i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.16b, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: cmlt v1.16b, v1.16b, #0 | |
| ; CHECK-GI-NEXT: cmgt v3.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i8>, <16 x i1>} @llvm.sadd.with.overflow(<16 x i8> %a, <16 x i8> %b) | |
| %e0 = extractvalue {<16 x i8>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i8>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i8> %e0, <16 x i8> %a | |
| ret <16 x i8> %r | |
| } | |
| define <16 x i8> @usub_v16i8(<16 x i8> %a, <16 x i8> %b) { | |
| ; CHECK-SD-LABEL: usub_v16i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: cmhi v2.16b, v1.16b, v0.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v16i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.16b, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: cmhi v1.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i8>, <16 x i1>} @llvm.usub.with.overflow(<16 x i8> %a, <16 x i8> %b) | |
| %e0 = extractvalue {<16 x i8>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i8>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i8> %e0, <16 x i8> %a | |
| ret <16 x i8> %r | |
| } | |
| define <16 x i8> @ssub_v16i8(<16 x i8> %a, <16 x i8> %b) { | |
| ; CHECK-SD-LABEL: ssub_v16i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: sub v1.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: cmeq v2.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v16i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.16b, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: cmgt v1.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: cmlt v3.16b, v2.16b, #0 | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i8>, <16 x i1>} @llvm.ssub.with.overflow(<16 x i8> %a, <16 x i8> %b) | |
| %e0 = extractvalue {<16 x i8>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i8>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i8> %e0, <16 x i8> %a | |
| ret <16 x i8> %r | |
| } | |
| define <16 x i8> @umul_v16i8(<16 x i8> %a, <16 x i8> %b) { | |
| ; CHECK-SD-LABEL: umul_v16i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull2 v2.8h, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: umull v3.8h, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: mul v1.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: uzp2 v2.16b, v3.16b, v2.16b | |
| ; CHECK-SD-NEXT: cmeq v2.16b, v2.16b, #0 | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v16i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull2 v2.8h, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: umull v3.8h, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: mul v1.16b, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: uzp2 v2.16b, v3.16b, v2.16b | |
| ; CHECK-GI-NEXT: cmtst v2.16b, v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i8>, <16 x i1>} @llvm.umul.with.overflow(<16 x i8> %a, <16 x i8> %b) | |
| %e0 = extractvalue {<16 x i8>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i8>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i8> %e0, <16 x i8> %a | |
| ret <16 x i8> %r | |
| } | |
| define <16 x i8> @smul_v16i8(<16 x i8> %a, <16 x i8> %b) { | |
| ; CHECK-SD-LABEL: smul_v16i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull2 v2.8h, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: smull v3.8h, v0.8b, v1.8b | |
| ; CHECK-SD-NEXT: mul v1.16b, v0.16b, v1.16b | |
| ; CHECK-SD-NEXT: uzp2 v2.16b, v3.16b, v2.16b | |
| ; CHECK-SD-NEXT: cmlt v3.16b, v1.16b, #0 | |
| ; CHECK-SD-NEXT: cmeq v2.16b, v2.16b, v3.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v16i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.16b, #127 | |
| ; CHECK-GI-NEXT: smull2 v3.8h, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: smull v4.8h, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: mul v1.16b, v0.16b, v1.16b | |
| ; CHECK-GI-NEXT: neg v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: uzp2 v3.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: sshl v2.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: cmeq v2.16b, v3.16b, v2.16b | |
| ; CHECK-GI-NEXT: mvn v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i8>, <16 x i1>} @llvm.smul.with.overflow(<16 x i8> %a, <16 x i8> %b) | |
| %e0 = extractvalue {<16 x i8>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i8>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i8> %e0, <16 x i8> %a | |
| ret <16 x i8> %r | |
| } | |
| define <32 x i8> @uadd_v32i8(<32 x i8> %a, <32 x i8> %b) { | |
| ; CHECK-SD-LABEL: uadd_v32i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v3.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: add v2.16b, v0.16b, v2.16b | |
| ; CHECK-SD-NEXT: cmhi v4.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: cmhi v5.16b, v0.16b, v2.16b | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v32i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v4.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: add v5.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: cmhi v2.16b, v2.16b, v4.16b | |
| ; CHECK-GI-NEXT: cmhi v3.16b, v3.16b, v5.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<32 x i8>, <32 x i1>} @llvm.uadd.with.overflow(<32 x i8> %a, <32 x i8> %b) | |
| %e0 = extractvalue {<32 x i8>, <32 x i1>} %o, 0 | |
| %e1 = extractvalue {<32 x i8>, <32 x i1>} %o, 1 | |
| %r = select <32 x i1> %e1, <32 x i8> %e0, <32 x i8> %a | |
| ret <32 x i8> %r | |
| } | |
| define <32 x i8> @sadd_v32i8(<32 x i8> %a, <32 x i8> %b) { | |
| ; CHECK-LABEL: sadd_v32i8: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: sqadd v4.16b, v1.16b, v3.16b | |
| ; CHECK-NEXT: sqadd v5.16b, v0.16b, v2.16b | |
| ; CHECK-NEXT: add v3.16b, v1.16b, v3.16b | |
| ; CHECK-NEXT: add v2.16b, v0.16b, v2.16b | |
| ; CHECK-NEXT: cmeq v4.16b, v3.16b, v4.16b | |
| ; CHECK-NEXT: cmeq v5.16b, v2.16b, v5.16b | |
| ; CHECK-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-NEXT: ret | |
| %o = call {<32 x i8>, <32 x i1>} @llvm.sadd.with.overflow(<32 x i8> %a, <32 x i8> %b) | |
| %e0 = extractvalue {<32 x i8>, <32 x i1>} %o, 0 | |
| %e1 = extractvalue {<32 x i8>, <32 x i1>} %o, 1 | |
| %r = select <32 x i1> %e1, <32 x i8> %e0, <32 x i8> %a | |
| ret <32 x i8> %r | |
| } | |
| define <32 x i8> @usub_v32i8(<32 x i8> %a, <32 x i8> %b) { | |
| ; CHECK-SD-LABEL: usub_v32i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v3.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: sub v2.16b, v0.16b, v2.16b | |
| ; CHECK-SD-NEXT: cmhi v4.16b, v3.16b, v1.16b | |
| ; CHECK-SD-NEXT: cmhi v5.16b, v2.16b, v0.16b | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v32i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v4.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: sub v5.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: cmhi v2.16b, v2.16b, v0.16b | |
| ; CHECK-GI-NEXT: cmhi v3.16b, v3.16b, v1.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<32 x i8>, <32 x i1>} @llvm.usub.with.overflow(<32 x i8> %a, <32 x i8> %b) | |
| %e0 = extractvalue {<32 x i8>, <32 x i1>} %o, 0 | |
| %e1 = extractvalue {<32 x i8>, <32 x i1>} %o, 1 | |
| %r = select <32 x i1> %e1, <32 x i8> %e0, <32 x i8> %a | |
| ret <32 x i8> %r | |
| } | |
| define <32 x i8> @ssub_v32i8(<32 x i8> %a, <32 x i8> %b) { | |
| ; CHECK-LABEL: ssub_v32i8: | |
| ; CHECK: // %bb.0: | |
| ; CHECK-NEXT: sqsub v4.16b, v1.16b, v3.16b | |
| ; CHECK-NEXT: sqsub v5.16b, v0.16b, v2.16b | |
| ; CHECK-NEXT: sub v3.16b, v1.16b, v3.16b | |
| ; CHECK-NEXT: sub v2.16b, v0.16b, v2.16b | |
| ; CHECK-NEXT: cmeq v4.16b, v3.16b, v4.16b | |
| ; CHECK-NEXT: cmeq v5.16b, v2.16b, v5.16b | |
| ; CHECK-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-NEXT: ret | |
| %o = call {<32 x i8>, <32 x i1>} @llvm.ssub.with.overflow(<32 x i8> %a, <32 x i8> %b) | |
| %e0 = extractvalue {<32 x i8>, <32 x i1>} %o, 0 | |
| %e1 = extractvalue {<32 x i8>, <32 x i1>} %o, 1 | |
| %r = select <32 x i1> %e1, <32 x i8> %e0, <32 x i8> %a | |
| ret <32 x i8> %r | |
| } | |
| define <32 x i8> @umul_v32i8(<32 x i8> %a, <32 x i8> %b) { | |
| ; CHECK-SD-LABEL: umul_v32i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull2 v4.8h, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: umull v5.8h, v1.8b, v3.8b | |
| ; CHECK-SD-NEXT: umull2 v6.8h, v0.16b, v2.16b | |
| ; CHECK-SD-NEXT: umull v7.8h, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: mul v3.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: mul v2.16b, v0.16b, v2.16b | |
| ; CHECK-SD-NEXT: uzp2 v4.16b, v5.16b, v4.16b | |
| ; CHECK-SD-NEXT: uzp2 v5.16b, v7.16b, v6.16b | |
| ; CHECK-SD-NEXT: cmeq v4.16b, v4.16b, #0 | |
| ; CHECK-SD-NEXT: cmeq v5.16b, v5.16b, #0 | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v32i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull v4.8h, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: umull2 v5.8h, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: umull v6.8h, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: umull2 v7.8h, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: mul v2.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: mul v3.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: uzp2 v4.16b, v4.16b, v5.16b | |
| ; CHECK-GI-NEXT: uzp2 v5.16b, v6.16b, v7.16b | |
| ; CHECK-GI-NEXT: cmtst v4.16b, v4.16b, v4.16b | |
| ; CHECK-GI-NEXT: cmtst v5.16b, v5.16b, v5.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v4.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v3.16b, v5.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<32 x i8>, <32 x i1>} @llvm.umul.with.overflow(<32 x i8> %a, <32 x i8> %b) | |
| %e0 = extractvalue {<32 x i8>, <32 x i1>} %o, 0 | |
| %e1 = extractvalue {<32 x i8>, <32 x i1>} %o, 1 | |
| %r = select <32 x i1> %e1, <32 x i8> %e0, <32 x i8> %a | |
| ret <32 x i8> %r | |
| } | |
| define <32 x i8> @smul_v32i8(<32 x i8> %a, <32 x i8> %b) { | |
| ; CHECK-SD-LABEL: smul_v32i8: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull2 v4.8h, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: smull v5.8h, v1.8b, v3.8b | |
| ; CHECK-SD-NEXT: smull2 v6.8h, v0.16b, v2.16b | |
| ; CHECK-SD-NEXT: smull v7.8h, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: mul v3.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: mul v2.16b, v0.16b, v2.16b | |
| ; CHECK-SD-NEXT: uzp2 v4.16b, v5.16b, v4.16b | |
| ; CHECK-SD-NEXT: uzp2 v5.16b, v7.16b, v6.16b | |
| ; CHECK-SD-NEXT: cmlt v6.16b, v3.16b, #0 | |
| ; CHECK-SD-NEXT: cmlt v7.16b, v2.16b, #0 | |
| ; CHECK-SD-NEXT: cmeq v4.16b, v4.16b, v6.16b | |
| ; CHECK-SD-NEXT: cmeq v5.16b, v5.16b, v7.16b | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v32i8: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v4.2d, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: smull v5.8h, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: smull v6.8h, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: smull2 v7.8h, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: mul v2.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: smull2 v16.8h, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: mul v3.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: neg v4.16b, v4.16b | |
| ; CHECK-GI-NEXT: shrn v5.8b, v5.8h, #8 | |
| ; CHECK-GI-NEXT: shrn v6.8b, v6.8h, #8 | |
| ; CHECK-GI-NEXT: sshl v17.16b, v2.16b, v4.16b | |
| ; CHECK-GI-NEXT: sshl v4.16b, v3.16b, v4.16b | |
| ; CHECK-GI-NEXT: shrn2 v5.16b, v7.8h, #8 | |
| ; CHECK-GI-NEXT: shrn2 v6.16b, v16.8h, #8 | |
| ; CHECK-GI-NEXT: cmeq v5.16b, v5.16b, v17.16b | |
| ; CHECK-GI-NEXT: cmeq v4.16b, v6.16b, v4.16b | |
| ; CHECK-GI-NEXT: mvn v5.16b, v5.16b | |
| ; CHECK-GI-NEXT: mvn v4.16b, v4.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<32 x i8>, <32 x i1>} @llvm.smul.with.overflow(<32 x i8> %a, <32 x i8> %b) | |
| %e0 = extractvalue {<32 x i8>, <32 x i1>} %o, 0 | |
| %e1 = extractvalue {<32 x i8>, <32 x i1>} %o, 1 | |
| %r = select <32 x i1> %e1, <32 x i8> %e0, <32 x i8> %a | |
| ret <32 x i8> %r | |
| } | |
| define <2 x i16> @uadd_v2i16(<2 x i16> %a, <2 x i16> %b) { | |
| ; CHECK-SD-LABEL: uadd_v2i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: movi d2, #0x00ffff0000ffff | |
| ; CHECK-SD-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: and v2.8b, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: add v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: fmov d2, d1 | |
| ; CHECK-SD-NEXT: bic v2.2s, #1, lsl #16 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v2i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi d2, #0x00ffff0000ffff | |
| ; CHECK-GI-NEXT: add v3.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: and v4.8b, v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: cmhi v1.2s, v1.2s, v4.2s | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i16>, <2 x i1>} @llvm.uadd.with.overflow(<2 x i16> %a, <2 x i16> %b) | |
| %e0 = extractvalue {<2 x i16>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i16>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i16> %e0, <2 x i16> %a | |
| ret <2 x i16> %r | |
| } | |
| define <2 x i16> @sadd_v2i16(<2 x i16> %a, <2 x i16> %b) { | |
| ; CHECK-SD-LABEL: sadd_v2i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v2.2s, v0.2s, #16 | |
| ; CHECK-SD-NEXT: shl v1.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #16 | |
| ; CHECK-SD-NEXT: ssra v2.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: shl v1.2s, v2.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v1.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: cmeq v1.2s, v1.2s, v2.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v2i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v3.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: shl v5.2s, v0.2s, #16 | |
| ; CHECK-GI-NEXT: shl v1.2s, v1.2s, #16 | |
| ; CHECK-GI-NEXT: shl v4.2s, v3.2s, #16 | |
| ; CHECK-GI-NEXT: sshr v5.2s, v5.2s, #16 | |
| ; CHECK-GI-NEXT: sshr v1.2s, v1.2s, #16 | |
| ; CHECK-GI-NEXT: sshll v2.4s, v2.4h, #0 | |
| ; CHECK-GI-NEXT: sshr v4.2s, v4.2s, #16 | |
| ; CHECK-GI-NEXT: cmgt v1.2s, v2.2s, v1.2s | |
| ; CHECK-GI-NEXT: movi d2, #0x00ffff0000ffff | |
| ; CHECK-GI-NEXT: cmgt v4.2s, v5.2s, v4.2s | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i16>, <2 x i1>} @llvm.sadd.with.overflow(<2 x i16> %a, <2 x i16> %b) | |
| %e0 = extractvalue {<2 x i16>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i16>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i16> %e0, <2 x i16> %a | |
| ret <2 x i16> %r | |
| } | |
| define <2 x i16> @usub_v2i16(<2 x i16> %a, <2 x i16> %b) { | |
| ; CHECK-SD-LABEL: usub_v2i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: movi d2, #0x00ffff0000ffff | |
| ; CHECK-SD-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: and v3.8b, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: sub v1.2s, v3.2s, v1.2s | |
| ; CHECK-SD-NEXT: and v2.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v2i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi d2, #0x00ffff0000ffff | |
| ; CHECK-GI-NEXT: sub v3.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: and v4.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: cmhi v1.2s, v1.2s, v4.2s | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i16>, <2 x i1>} @llvm.usub.with.overflow(<2 x i16> %a, <2 x i16> %b) | |
| %e0 = extractvalue {<2 x i16>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i16>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i16> %e0, <2 x i16> %a | |
| ret <2 x i16> %r | |
| } | |
| define <2 x i16> @ssub_v2i16(<2 x i16> %a, <2 x i16> %b) { | |
| ; CHECK-SD-LABEL: ssub_v2i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v1.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: shl v2.2s, v0.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v1.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #16 | |
| ; CHECK-SD-NEXT: sub v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: shl v2.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #16 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v2i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v3.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: shl v4.2s, v0.2s, #16 | |
| ; CHECK-GI-NEXT: shl v1.2s, v1.2s, #16 | |
| ; CHECK-GI-NEXT: shl v5.2s, v3.2s, #16 | |
| ; CHECK-GI-NEXT: sshr v4.2s, v4.2s, #16 | |
| ; CHECK-GI-NEXT: sshr v1.2s, v1.2s, #16 | |
| ; CHECK-GI-NEXT: sshll v2.4s, v2.4h, #0 | |
| ; CHECK-GI-NEXT: sshr v5.2s, v5.2s, #16 | |
| ; CHECK-GI-NEXT: cmgt v1.2s, v1.2s, v4.2s | |
| ; CHECK-GI-NEXT: movi d4, #0x00ffff0000ffff | |
| ; CHECK-GI-NEXT: cmgt v2.2s, v2.2s, v5.2s | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i16>, <2 x i1>} @llvm.ssub.with.overflow(<2 x i16> %a, <2 x i16> %b) | |
| %e0 = extractvalue {<2 x i16>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i16>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i16> %e0, <2 x i16> %a | |
| ret <2 x i16> %r | |
| } | |
| define <2 x i16> @umul_v2i16(<2 x i16> %a, <2 x i16> %b) { | |
| ; CHECK-SD-LABEL: umul_v2i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: movi d2, #0x00ffff0000ffff | |
| ; CHECK-SD-NEXT: and v1.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: and v2.8b, v0.8b, v2.8b | |
| ; CHECK-SD-NEXT: mul v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: ushr v2.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v2i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi d2, #0x00ffff0000ffff | |
| ; CHECK-GI-NEXT: and v3.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v4.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: mul v1.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mul v3.2s, v3.2s, v4.2s | |
| ; CHECK-GI-NEXT: movi v4.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: ushr v3.2s, v3.2s, #16 | |
| ; CHECK-GI-NEXT: ushll v4.4s, v4.4h, #0 | |
| ; CHECK-GI-NEXT: cmeq v3.2s, v3.2s, v4.2s | |
| ; CHECK-GI-NEXT: mvn v4.8b, v3.8b | |
| ; CHECK-GI-NEXT: bic v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: eor v2.8b, v4.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i16>, <2 x i1>} @llvm.umul.with.overflow(<2 x i16> %a, <2 x i16> %b) | |
| %e0 = extractvalue {<2 x i16>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i16>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i16> %e0, <2 x i16> %a | |
| ret <2 x i16> %r | |
| } | |
| define <2 x i16> @smul_v2i16(<2 x i16> %a, <2 x i16> %b) { | |
| ; CHECK-SD-LABEL: smul_v2i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: shl v1.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: shl v2.2s, v0.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v1.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #16 | |
| ; CHECK-SD-NEXT: mul v1.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: shl v2.2s, v1.2s, #16 | |
| ; CHECK-SD-NEXT: sshr v2.2s, v2.2s, #16 | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, v1.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v2i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: shl v3.2s, v0.2s, #16 | |
| ; CHECK-GI-NEXT: shl v4.2s, v1.2s, #16 | |
| ; CHECK-GI-NEXT: mul v1.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: movi v2.4h, #31 | |
| ; CHECK-GI-NEXT: movi d5, #0x00ffff0000ffff | |
| ; CHECK-GI-NEXT: sshr v3.2s, v3.2s, #16 | |
| ; CHECK-GI-NEXT: sshr v4.2s, v4.2s, #16 | |
| ; CHECK-GI-NEXT: neg v2.4h, v2.4h | |
| ; CHECK-GI-NEXT: mul v3.2s, v3.2s, v4.2s | |
| ; CHECK-GI-NEXT: uzp1 v4.4h, v1.4h, v0.4h | |
| ; CHECK-GI-NEXT: sshl v2.4h, v4.4h, v2.4h | |
| ; CHECK-GI-NEXT: sshr v3.2s, v3.2s, #16 | |
| ; CHECK-GI-NEXT: and v3.8b, v3.8b, v5.8b | |
| ; CHECK-GI-NEXT: ushll v2.4s, v2.4h, #0 | |
| ; CHECK-GI-NEXT: cmeq v2.2s, v3.2s, v2.2s | |
| ; CHECK-GI-NEXT: mvn v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: bic v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: eor v3.8b, v3.8b, v5.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i16>, <2 x i1>} @llvm.smul.with.overflow(<2 x i16> %a, <2 x i16> %b) | |
| %e0 = extractvalue {<2 x i16>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i16>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i16> %e0, <2 x i16> %a | |
| ret <2 x i16> %r | |
| } | |
| define <3 x i16> @uadd_v3i16(<3 x i16> %a, <3 x i16> %b) { | |
| ; CHECK-SD-LABEL: uadd_v3i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmhi v2.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v3i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v3.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: movi d2, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: cmhi v1.4h, v1.4h, v3.4h | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i16>, <3 x i1>} @llvm.uadd.with.overflow(<3 x i16> %a, <3 x i16> %b) | |
| %e0 = extractvalue {<3 x i16>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i16>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i16> %e0, <3 x i16> %a | |
| ret <3 x i16> %r | |
| } | |
| define <3 x i16> @sadd_v3i16(<3 x i16> %a, <3 x i16> %b) { | |
| ; CHECK-SD-LABEL: sadd_v3i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: add v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v1.4h, v2.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v3i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: add v3.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: cmgt v4.4h, v0.4h, v3.4h | |
| ; CHECK-GI-NEXT: cmgt v1.4h, v2.4h, v1.4h | |
| ; CHECK-GI-NEXT: movi d2, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i16>, <3 x i1>} @llvm.sadd.with.overflow(<3 x i16> %a, <3 x i16> %b) | |
| %e0 = extractvalue {<3 x i16>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i16>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i16> %e0, <3 x i16> %a | |
| ret <3 x i16> %r | |
| } | |
| define <3 x i16> @usub_v3i16(<3 x i16> %a, <3 x i16> %b) { | |
| ; CHECK-SD-LABEL: usub_v3i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmhi v2.4h, v1.4h, v0.4h | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v3i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi d2, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: cmhi v3.4h, v1.4h, v0.4h | |
| ; CHECK-GI-NEXT: sub v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: and v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: eor v2.8b, v3.8b, v2.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i16>, <3 x i1>} @llvm.usub.with.overflow(<3 x i16> %a, <3 x i16> %b) | |
| %e0 = extractvalue {<3 x i16>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i16>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i16> %e0, <3 x i16> %a | |
| ret <3 x i16> %r | |
| } | |
| define <3 x i16> @ssub_v3i16(<3 x i16> %a, <3 x i16> %b) { | |
| ; CHECK-SD-LABEL: ssub_v3i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: sub v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v1.4h, v2.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v3i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: sub v3.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: cmgt v1.4h, v1.4h, v0.4h | |
| ; CHECK-GI-NEXT: movi d4, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: cmgt v2.4h, v2.4h, v3.4h | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: eor v2.8b, v1.8b, v4.8b | |
| ; CHECK-GI-NEXT: and v1.8b, v3.8b, v1.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i16>, <3 x i1>} @llvm.ssub.with.overflow(<3 x i16> %a, <3 x i16> %b) | |
| %e0 = extractvalue {<3 x i16>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i16>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i16> %e0, <3 x i16> %a | |
| ret <3 x i16> %r | |
| } | |
| define <3 x i16> @umul_v3i16(<3 x i16> %a, <3 x i16> %b) { | |
| ; CHECK-SD-LABEL: umul_v3i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull v1.4s, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: shrn v2.4h, v1.4s, #16 | |
| ; CHECK-SD-NEXT: xtn v1.4h, v1.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v3i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: umov w8, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w9, v1.h[0] | |
| ; CHECK-GI-NEXT: umov w10, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w11, v1.h[1] | |
| ; CHECK-GI-NEXT: fmov s2, w8 | |
| ; CHECK-GI-NEXT: fmov s3, w9 | |
| ; CHECK-GI-NEXT: umov w8, v0.h[2] | |
| ; CHECK-GI-NEXT: umov w9, v1.h[2] | |
| ; CHECK-GI-NEXT: mul v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: mov v2.s[1], w10 | |
| ; CHECK-GI-NEXT: mov v3.s[1], w11 | |
| ; CHECK-GI-NEXT: mov v2.s[2], w8 | |
| ; CHECK-GI-NEXT: mov v3.s[2], w9 | |
| ; CHECK-GI-NEXT: mul v2.4s, v2.4s, v3.4s | |
| ; CHECK-GI-NEXT: movi v3.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: shrn v2.4h, v2.4s, #16 | |
| ; CHECK-GI-NEXT: cmeq v2.4h, v2.4h, v3.4h | |
| ; CHECK-GI-NEXT: movi d3, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: mvn v4.8b, v2.8b | |
| ; CHECK-GI-NEXT: bic v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: eor v3.8b, v4.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i16>, <3 x i1>} @llvm.umul.with.overflow(<3 x i16> %a, <3 x i16> %b) | |
| %e0 = extractvalue {<3 x i16>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i16>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i16> %e0, <3 x i16> %a | |
| ret <3 x i16> %r | |
| } | |
| define <3 x i16> @smul_v3i16(<3 x i16> %a, <3 x i16> %b) { | |
| ; CHECK-SD-LABEL: smul_v3i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull v1.4s, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: xtn v2.4h, v1.4s | |
| ; CHECK-SD-NEXT: shrn v1.4h, v1.4s, #16 | |
| ; CHECK-SD-NEXT: cmlt v3.4h, v2.4h, #0 | |
| ; CHECK-SD-NEXT: cmeq v1.4h, v1.4h, v3.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v3i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: smov w8, v0.h[0] | |
| ; CHECK-GI-NEXT: smov w9, v1.h[0] | |
| ; CHECK-GI-NEXT: smov w10, v0.h[1] | |
| ; CHECK-GI-NEXT: smov w11, v1.h[1] | |
| ; CHECK-GI-NEXT: movi v2.4h, #47 | |
| ; CHECK-GI-NEXT: fmov s3, w8 | |
| ; CHECK-GI-NEXT: fmov s4, w9 | |
| ; CHECK-GI-NEXT: smov w8, v0.h[2] | |
| ; CHECK-GI-NEXT: smov w9, v1.h[2] | |
| ; CHECK-GI-NEXT: mul v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: neg v2.4h, v2.4h | |
| ; CHECK-GI-NEXT: mov v3.s[1], w10 | |
| ; CHECK-GI-NEXT: mov v4.s[1], w11 | |
| ; CHECK-GI-NEXT: sshl v2.4h, v1.4h, v2.4h | |
| ; CHECK-GI-NEXT: mov v3.s[2], w8 | |
| ; CHECK-GI-NEXT: mov v4.s[2], w9 | |
| ; CHECK-GI-NEXT: mul v3.4s, v3.4s, v4.4s | |
| ; CHECK-GI-NEXT: shrn v3.4h, v3.4s, #16 | |
| ; CHECK-GI-NEXT: cmeq v2.4h, v3.4h, v2.4h | |
| ; CHECK-GI-NEXT: movi d3, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: mvn v4.8b, v2.8b | |
| ; CHECK-GI-NEXT: bic v1.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: eor v3.8b, v4.8b, v3.8b | |
| ; CHECK-GI-NEXT: and v0.8b, v0.8b, v3.8b | |
| ; CHECK-GI-NEXT: orr v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i16>, <3 x i1>} @llvm.smul.with.overflow(<3 x i16> %a, <3 x i16> %b) | |
| %e0 = extractvalue {<3 x i16>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i16>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i16> %e0, <3 x i16> %a | |
| ret <3 x i16> %r | |
| } | |
| define <4 x i16> @uadd_v4i16(<4 x i16> %a, <4 x i16> %b) { | |
| ; CHECK-SD-LABEL: uadd_v4i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmhi v2.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v4i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: cmhi v1.4h, v1.4h, v2.4h | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i16>, <4 x i1>} @llvm.uadd.with.overflow(<4 x i16> %a, <4 x i16> %b) | |
| %e0 = extractvalue {<4 x i16>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i16>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i16> %e0, <4 x i16> %a | |
| ret <4 x i16> %r | |
| } | |
| define <4 x i16> @sadd_v4i16(<4 x i16> %a, <4 x i16> %b) { | |
| ; CHECK-SD-LABEL: sadd_v4i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: add v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v1.4h, v2.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v4i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: cmlt v1.4h, v1.4h, #0 | |
| ; CHECK-GI-NEXT: cmgt v3.4h, v0.4h, v2.4h | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i16>, <4 x i1>} @llvm.sadd.with.overflow(<4 x i16> %a, <4 x i16> %b) | |
| %e0 = extractvalue {<4 x i16>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i16>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i16> %e0, <4 x i16> %a | |
| ret <4 x i16> %r | |
| } | |
| define <4 x i16> @usub_v4i16(<4 x i16> %a, <4 x i16> %b) { | |
| ; CHECK-SD-LABEL: usub_v4i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmhi v2.4h, v1.4h, v0.4h | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v4i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: cmhi v1.4h, v1.4h, v0.4h | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i16>, <4 x i1>} @llvm.usub.with.overflow(<4 x i16> %a, <4 x i16> %b) | |
| %e0 = extractvalue {<4 x i16>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i16>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i16> %e0, <4 x i16> %a | |
| ret <4 x i16> %r | |
| } | |
| define <4 x i16> @ssub_v4i16(<4 x i16> %a, <4 x i16> %b) { | |
| ; CHECK-SD-LABEL: ssub_v4i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: sub v1.4h, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v1.4h, v2.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v4i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: cmgt v1.4h, v1.4h, v0.4h | |
| ; CHECK-GI-NEXT: cmlt v3.4h, v2.4h, #0 | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i16>, <4 x i1>} @llvm.ssub.with.overflow(<4 x i16> %a, <4 x i16> %b) | |
| %e0 = extractvalue {<4 x i16>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i16>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i16> %e0, <4 x i16> %a | |
| ret <4 x i16> %r | |
| } | |
| define <4 x i16> @umul_v4i16(<4 x i16> %a, <4 x i16> %b) { | |
| ; CHECK-SD-LABEL: umul_v4i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull v1.4s, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: shrn v2.4h, v1.4s, #16 | |
| ; CHECK-SD-NEXT: xtn v1.4h, v1.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4h, v2.4h, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v4i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull v2.4s, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: mul v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: shrn v2.4h, v2.4s, #16 | |
| ; CHECK-GI-NEXT: cmtst v2.4h, v2.4h, v2.4h | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i16>, <4 x i1>} @llvm.umul.with.overflow(<4 x i16> %a, <4 x i16> %b) | |
| %e0 = extractvalue {<4 x i16>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i16>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i16> %e0, <4 x i16> %a | |
| ret <4 x i16> %r | |
| } | |
| define <4 x i16> @smul_v4i16(<4 x i16> %a, <4 x i16> %b) { | |
| ; CHECK-SD-LABEL: smul_v4i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull v1.4s, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: xtn v2.4h, v1.4s | |
| ; CHECK-SD-NEXT: shrn v1.4h, v1.4s, #16 | |
| ; CHECK-SD-NEXT: cmlt v3.4h, v2.4h, #0 | |
| ; CHECK-SD-NEXT: cmeq v1.4h, v1.4h, v3.4h | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v4i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.4h, #63 | |
| ; CHECK-GI-NEXT: smull v3.4s, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: mul v1.4h, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: neg v2.4h, v2.4h | |
| ; CHECK-GI-NEXT: shrn v3.4h, v3.4s, #16 | |
| ; CHECK-GI-NEXT: sshl v2.4h, v1.4h, v2.4h | |
| ; CHECK-GI-NEXT: cmeq v2.4h, v3.4h, v2.4h | |
| ; CHECK-GI-NEXT: mvn v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i16>, <4 x i1>} @llvm.smul.with.overflow(<4 x i16> %a, <4 x i16> %b) | |
| %e0 = extractvalue {<4 x i16>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i16>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i16> %e0, <4 x i16> %a | |
| ret <4 x i16> %r | |
| } | |
| define <8 x i16> @uadd_v8i16(<8 x i16> %a, <8 x i16> %b) { | |
| ; CHECK-SD-LABEL: uadd_v8i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: cmhi v2.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v8i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.8h, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: cmhi v1.8h, v1.8h, v2.8h | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i16>, <8 x i1>} @llvm.uadd.with.overflow(<8 x i16> %a, <8 x i16> %b) | |
| %e0 = extractvalue {<8 x i16>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i16>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i16> %e0, <8 x i16> %a | |
| ret <8 x i16> %r | |
| } | |
| define <8 x i16> @sadd_v8i16(<8 x i16> %a, <8 x i16> %b) { | |
| ; CHECK-SD-LABEL: sadd_v8i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: add v1.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: cmeq v2.8h, v1.8h, v2.8h | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v8i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.8h, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: cmlt v1.8h, v1.8h, #0 | |
| ; CHECK-GI-NEXT: cmgt v3.8h, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i16>, <8 x i1>} @llvm.sadd.with.overflow(<8 x i16> %a, <8 x i16> %b) | |
| %e0 = extractvalue {<8 x i16>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i16>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i16> %e0, <8 x i16> %a | |
| ret <8 x i16> %r | |
| } | |
| define <8 x i16> @usub_v8i16(<8 x i16> %a, <8 x i16> %b) { | |
| ; CHECK-SD-LABEL: usub_v8i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: cmhi v2.8h, v1.8h, v0.8h | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v8i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.8h, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: cmhi v1.8h, v1.8h, v0.8h | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i16>, <8 x i1>} @llvm.usub.with.overflow(<8 x i16> %a, <8 x i16> %b) | |
| %e0 = extractvalue {<8 x i16>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i16>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i16> %e0, <8 x i16> %a | |
| ret <8 x i16> %r | |
| } | |
| define <8 x i16> @ssub_v8i16(<8 x i16> %a, <8 x i16> %b) { | |
| ; CHECK-SD-LABEL: ssub_v8i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: sub v1.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: cmeq v2.8h, v1.8h, v2.8h | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v8i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.8h, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: cmgt v1.8h, v1.8h, v0.8h | |
| ; CHECK-GI-NEXT: cmlt v3.8h, v2.8h, #0 | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i16>, <8 x i1>} @llvm.ssub.with.overflow(<8 x i16> %a, <8 x i16> %b) | |
| %e0 = extractvalue {<8 x i16>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i16>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i16> %e0, <8 x i16> %a | |
| ret <8 x i16> %r | |
| } | |
| define <8 x i16> @umul_v8i16(<8 x i16> %a, <8 x i16> %b) { | |
| ; CHECK-SD-LABEL: umul_v8i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull2 v2.4s, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: umull v3.4s, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: mul v1.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: uzp2 v2.8h, v3.8h, v2.8h | |
| ; CHECK-SD-NEXT: cmeq v2.8h, v2.8h, #0 | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v8i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull2 v2.4s, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: umull v3.4s, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: mul v1.8h, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: uzp2 v2.8h, v3.8h, v2.8h | |
| ; CHECK-GI-NEXT: cmtst v2.8h, v2.8h, v2.8h | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i16>, <8 x i1>} @llvm.umul.with.overflow(<8 x i16> %a, <8 x i16> %b) | |
| %e0 = extractvalue {<8 x i16>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i16>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i16> %e0, <8 x i16> %a | |
| ret <8 x i16> %r | |
| } | |
| define <8 x i16> @smul_v8i16(<8 x i16> %a, <8 x i16> %b) { | |
| ; CHECK-SD-LABEL: smul_v8i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull2 v2.4s, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: smull v3.4s, v0.4h, v1.4h | |
| ; CHECK-SD-NEXT: mul v1.8h, v0.8h, v1.8h | |
| ; CHECK-SD-NEXT: uzp2 v2.8h, v3.8h, v2.8h | |
| ; CHECK-SD-NEXT: cmlt v3.8h, v1.8h, #0 | |
| ; CHECK-SD-NEXT: cmeq v2.8h, v2.8h, v3.8h | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v8i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.8h, #127 | |
| ; CHECK-GI-NEXT: smull2 v3.4s, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: smull v4.4s, v0.4h, v1.4h | |
| ; CHECK-GI-NEXT: mul v1.8h, v0.8h, v1.8h | |
| ; CHECK-GI-NEXT: neg v2.8h, v2.8h | |
| ; CHECK-GI-NEXT: uzp2 v3.8h, v4.8h, v3.8h | |
| ; CHECK-GI-NEXT: sshl v2.8h, v1.8h, v2.8h | |
| ; CHECK-GI-NEXT: cmeq v2.8h, v3.8h, v2.8h | |
| ; CHECK-GI-NEXT: mvn v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i16>, <8 x i1>} @llvm.smul.with.overflow(<8 x i16> %a, <8 x i16> %b) | |
| %e0 = extractvalue {<8 x i16>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i16>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i16> %e0, <8 x i16> %a | |
| ret <8 x i16> %r | |
| } | |
| define <16 x i16> @uadd_v16i16(<16 x i16> %a, <16 x i16> %b) { | |
| ; CHECK-SD-LABEL: uadd_v16i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v3.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: add v2.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: cmhi v4.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: cmhi v5.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v16i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v4.8h, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: add v5.8h, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: cmhi v2.8h, v2.8h, v4.8h | |
| ; CHECK-GI-NEXT: cmhi v3.8h, v3.8h, v5.8h | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i16>, <16 x i1>} @llvm.uadd.with.overflow(<16 x i16> %a, <16 x i16> %b) | |
| %e0 = extractvalue {<16 x i16>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i16>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i16> %e0, <16 x i16> %a | |
| ret <16 x i16> %r | |
| } | |
| define <16 x i16> @sadd_v16i16(<16 x i16> %a, <16 x i16> %b) { | |
| ; CHECK-SD-LABEL: sadd_v16i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v4.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: sqadd v5.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: add v3.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: add v2.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: cmeq v4.8h, v3.8h, v4.8h | |
| ; CHECK-SD-NEXT: cmeq v5.8h, v2.8h, v5.8h | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v16i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v4.8h, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: add v5.8h, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: cmlt v2.8h, v2.8h, #0 | |
| ; CHECK-GI-NEXT: cmlt v3.8h, v3.8h, #0 | |
| ; CHECK-GI-NEXT: cmgt v6.8h, v0.8h, v4.8h | |
| ; CHECK-GI-NEXT: cmgt v7.8h, v1.8h, v5.8h | |
| ; CHECK-GI-NEXT: uzp1 v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: uzp1 v3.16b, v6.16b, v7.16b | |
| ; CHECK-GI-NEXT: eor v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: sshll v3.8h, v2.8b, #0 | |
| ; CHECK-GI-NEXT: sshll2 v2.8h, v2.16b, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i16>, <16 x i1>} @llvm.sadd.with.overflow(<16 x i16> %a, <16 x i16> %b) | |
| %e0 = extractvalue {<16 x i16>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i16>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i16> %e0, <16 x i16> %a | |
| ret <16 x i16> %r | |
| } | |
| define <16 x i16> @usub_v16i16(<16 x i16> %a, <16 x i16> %b) { | |
| ; CHECK-SD-LABEL: usub_v16i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v3.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: sub v2.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: cmhi v4.8h, v3.8h, v1.8h | |
| ; CHECK-SD-NEXT: cmhi v5.8h, v2.8h, v0.8h | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v16i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v4.8h, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: sub v5.8h, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: cmhi v2.8h, v2.8h, v0.8h | |
| ; CHECK-GI-NEXT: cmhi v3.8h, v3.8h, v1.8h | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i16>, <16 x i1>} @llvm.usub.with.overflow(<16 x i16> %a, <16 x i16> %b) | |
| %e0 = extractvalue {<16 x i16>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i16>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i16> %e0, <16 x i16> %a | |
| ret <16 x i16> %r | |
| } | |
| define <16 x i16> @ssub_v16i16(<16 x i16> %a, <16 x i16> %b) { | |
| ; CHECK-SD-LABEL: ssub_v16i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v4.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: sqsub v5.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: sub v3.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: sub v2.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: cmeq v4.8h, v3.8h, v4.8h | |
| ; CHECK-SD-NEXT: cmeq v5.8h, v2.8h, v5.8h | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v16i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v4.8h, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: sub v5.8h, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: cmgt v2.8h, v2.8h, v0.8h | |
| ; CHECK-GI-NEXT: cmgt v3.8h, v3.8h, v1.8h | |
| ; CHECK-GI-NEXT: cmlt v6.8h, v4.8h, #0 | |
| ; CHECK-GI-NEXT: cmlt v7.8h, v5.8h, #0 | |
| ; CHECK-GI-NEXT: uzp1 v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: uzp1 v3.16b, v6.16b, v7.16b | |
| ; CHECK-GI-NEXT: eor v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: sshll v3.8h, v2.8b, #0 | |
| ; CHECK-GI-NEXT: sshll2 v2.8h, v2.16b, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i16>, <16 x i1>} @llvm.ssub.with.overflow(<16 x i16> %a, <16 x i16> %b) | |
| %e0 = extractvalue {<16 x i16>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i16>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i16> %e0, <16 x i16> %a | |
| ret <16 x i16> %r | |
| } | |
| define <16 x i16> @umul_v16i16(<16 x i16> %a, <16 x i16> %b) { | |
| ; CHECK-SD-LABEL: umul_v16i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull2 v4.4s, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: umull v5.4s, v1.4h, v3.4h | |
| ; CHECK-SD-NEXT: umull2 v6.4s, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: umull v7.4s, v0.4h, v2.4h | |
| ; CHECK-SD-NEXT: mul v3.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: mul v2.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: uzp2 v4.8h, v5.8h, v4.8h | |
| ; CHECK-SD-NEXT: uzp2 v5.8h, v7.8h, v6.8h | |
| ; CHECK-SD-NEXT: cmeq v4.8h, v4.8h, #0 | |
| ; CHECK-SD-NEXT: cmeq v5.8h, v5.8h, #0 | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v16i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull v4.4s, v0.4h, v2.4h | |
| ; CHECK-GI-NEXT: umull2 v5.4s, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: umull v6.4s, v1.4h, v3.4h | |
| ; CHECK-GI-NEXT: umull2 v7.4s, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: mul v2.8h, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: mul v3.8h, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: uzp2 v4.8h, v4.8h, v5.8h | |
| ; CHECK-GI-NEXT: uzp2 v5.8h, v6.8h, v7.8h | |
| ; CHECK-GI-NEXT: cmtst v4.8h, v4.8h, v4.8h | |
| ; CHECK-GI-NEXT: cmtst v5.8h, v5.8h, v5.8h | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v4.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v3.16b, v5.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i16>, <16 x i1>} @llvm.umul.with.overflow(<16 x i16> %a, <16 x i16> %b) | |
| %e0 = extractvalue {<16 x i16>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i16>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i16> %e0, <16 x i16> %a | |
| ret <16 x i16> %r | |
| } | |
| define <16 x i16> @smul_v16i16(<16 x i16> %a, <16 x i16> %b) { | |
| ; CHECK-SD-LABEL: smul_v16i16: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull2 v4.4s, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: smull v5.4s, v1.4h, v3.4h | |
| ; CHECK-SD-NEXT: smull2 v6.4s, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: smull v7.4s, v0.4h, v2.4h | |
| ; CHECK-SD-NEXT: mul v3.8h, v1.8h, v3.8h | |
| ; CHECK-SD-NEXT: mul v2.8h, v0.8h, v2.8h | |
| ; CHECK-SD-NEXT: uzp2 v4.8h, v5.8h, v4.8h | |
| ; CHECK-SD-NEXT: uzp2 v5.8h, v7.8h, v6.8h | |
| ; CHECK-SD-NEXT: cmlt v6.8h, v3.8h, #0 | |
| ; CHECK-SD-NEXT: cmlt v7.8h, v2.8h, #0 | |
| ; CHECK-SD-NEXT: cmeq v4.8h, v4.8h, v6.8h | |
| ; CHECK-SD-NEXT: cmeq v5.8h, v5.8h, v7.8h | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v16i16: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v4.2d, #0xff00ff00ff00ff | |
| ; CHECK-GI-NEXT: smull v5.4s, v0.4h, v2.4h | |
| ; CHECK-GI-NEXT: smull v6.4s, v1.4h, v3.4h | |
| ; CHECK-GI-NEXT: smull2 v7.4s, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: mul v2.8h, v0.8h, v2.8h | |
| ; CHECK-GI-NEXT: smull2 v16.4s, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: mul v3.8h, v1.8h, v3.8h | |
| ; CHECK-GI-NEXT: neg v4.8h, v4.8h | |
| ; CHECK-GI-NEXT: shrn v5.4h, v5.4s, #16 | |
| ; CHECK-GI-NEXT: shrn v6.4h, v6.4s, #16 | |
| ; CHECK-GI-NEXT: sshl v17.8h, v2.8h, v4.8h | |
| ; CHECK-GI-NEXT: sshl v4.8h, v3.8h, v4.8h | |
| ; CHECK-GI-NEXT: shrn2 v5.8h, v7.4s, #16 | |
| ; CHECK-GI-NEXT: shrn2 v6.8h, v16.4s, #16 | |
| ; CHECK-GI-NEXT: cmeq v5.8h, v5.8h, v17.8h | |
| ; CHECK-GI-NEXT: cmeq v4.8h, v6.8h, v4.8h | |
| ; CHECK-GI-NEXT: mvn v5.16b, v5.16b | |
| ; CHECK-GI-NEXT: mvn v4.16b, v4.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<16 x i16>, <16 x i1>} @llvm.smul.with.overflow(<16 x i16> %a, <16 x i16> %b) | |
| %e0 = extractvalue {<16 x i16>, <16 x i1>} %o, 0 | |
| %e1 = extractvalue {<16 x i16>, <16 x i1>} %o, 1 | |
| %r = select <16 x i1> %e1, <16 x i16> %e0, <16 x i16> %a | |
| ret <16 x i16> %r | |
| } | |
| define <2 x i32> @uadd_v2i32(<2 x i32> %a, <2 x i32> %b) { | |
| ; CHECK-SD-LABEL: uadd_v2i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.2s, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: cmhi v2.2s, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v2i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: cmhi v1.2s, v1.2s, v2.2s | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i32>, <2 x i1>} @llvm.uadd.with.overflow(<2 x i32> %a, <2 x i32> %b) | |
| %e0 = extractvalue {<2 x i32>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i32>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i32> %e0, <2 x i32> %a | |
| ret <2 x i32> %r | |
| } | |
| define <2 x i32> @sadd_v2i32(<2 x i32> %a, <2 x i32> %b) { | |
| ; CHECK-SD-LABEL: sadd_v2i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.2s, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: add v1.2s, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v1.2s, v2.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v2i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: cmlt v1.2s, v1.2s, #0 | |
| ; CHECK-GI-NEXT: cmgt v3.2s, v0.2s, v2.2s | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i32>, <2 x i1>} @llvm.sadd.with.overflow(<2 x i32> %a, <2 x i32> %b) | |
| %e0 = extractvalue {<2 x i32>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i32>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i32> %e0, <2 x i32> %a | |
| ret <2 x i32> %r | |
| } | |
| define <2 x i32> @usub_v2i32(<2 x i32> %a, <2 x i32> %b) { | |
| ; CHECK-SD-LABEL: usub_v2i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.2s, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: cmhi v2.2s, v1.2s, v0.2s | |
| ; CHECK-SD-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v2i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: cmhi v1.2s, v1.2s, v0.2s | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i32>, <2 x i1>} @llvm.usub.with.overflow(<2 x i32> %a, <2 x i32> %b) | |
| %e0 = extractvalue {<2 x i32>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i32>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i32> %e0, <2 x i32> %a | |
| ret <2 x i32> %r | |
| } | |
| define <2 x i32> @ssub_v2i32(<2 x i32> %a, <2 x i32> %b) { | |
| ; CHECK-SD-LABEL: ssub_v2i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.2s, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: sub v1.2s, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v1.2s, v2.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v2i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: cmgt v1.2s, v1.2s, v0.2s | |
| ; CHECK-GI-NEXT: cmlt v3.2s, v2.2s, #0 | |
| ; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v2.8b, v1.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i32>, <2 x i1>} @llvm.ssub.with.overflow(<2 x i32> %a, <2 x i32> %b) | |
| %e0 = extractvalue {<2 x i32>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i32>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i32> %e0, <2 x i32> %a | |
| ret <2 x i32> %r | |
| } | |
| define <2 x i32> @umul_v2i32(<2 x i32> %a, <2 x i32> %b) { | |
| ; CHECK-SD-LABEL: umul_v2i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull v1.2d, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: shrn v2.2s, v1.2d, #32 | |
| ; CHECK-SD-NEXT: xtn v1.2s, v1.2d | |
| ; CHECK-SD-NEXT: cmeq v2.2s, v2.2s, #0 | |
| ; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v2i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull v2.2d, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mul v1.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: shrn v2.2s, v2.2d, #32 | |
| ; CHECK-GI-NEXT: cmtst v2.2s, v2.2s, v2.2s | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i32>, <2 x i1>} @llvm.umul.with.overflow(<2 x i32> %a, <2 x i32> %b) | |
| %e0 = extractvalue {<2 x i32>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i32>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i32> %e0, <2 x i32> %a | |
| ret <2 x i32> %r | |
| } | |
| define <2 x i32> @smul_v2i32(<2 x i32> %a, <2 x i32> %b) { | |
| ; CHECK-SD-LABEL: smul_v2i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull v1.2d, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: xtn v2.2s, v1.2d | |
| ; CHECK-SD-NEXT: shrn v1.2s, v1.2d, #32 | |
| ; CHECK-SD-NEXT: cmlt v3.2s, v2.2s, #0 | |
| ; CHECK-SD-NEXT: cmeq v1.2s, v1.2s, v3.2s | |
| ; CHECK-SD-NEXT: bif v0.8b, v2.8b, v1.8b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v2i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.2s, #63 | |
| ; CHECK-GI-NEXT: smull v3.2d, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mul v1.2s, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: neg v2.2s, v2.2s | |
| ; CHECK-GI-NEXT: shrn v3.2s, v3.2d, #32 | |
| ; CHECK-GI-NEXT: sshl v2.2s, v1.2s, v2.2s | |
| ; CHECK-GI-NEXT: cmeq v2.2s, v3.2s, v2.2s | |
| ; CHECK-GI-NEXT: mvn v2.8b, v2.8b | |
| ; CHECK-GI-NEXT: bit v0.8b, v1.8b, v2.8b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i32>, <2 x i1>} @llvm.smul.with.overflow(<2 x i32> %a, <2 x i32> %b) | |
| %e0 = extractvalue {<2 x i32>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i32>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i32> %e0, <2 x i32> %a | |
| ret <2 x i32> %r | |
| } | |
| define <3 x i32> @uadd_v3i32(<3 x i32> %a, <3 x i32> %b) { | |
| ; CHECK-SD-LABEL: uadd_v3i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmhi v2.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v3i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v3.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: movi v2.2d, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: cmhi v1.4s, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: eor v2.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: and v1.16b, v3.16b, v1.16b | |
| ; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: orr v0.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i32>, <3 x i1>} @llvm.uadd.with.overflow(<3 x i32> %a, <3 x i32> %b) | |
| %e0 = extractvalue {<3 x i32>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i32>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i32> %e0, <3 x i32> %a | |
| ret <3 x i32> %r | |
| } | |
| define <3 x i32> @sadd_v3i32(<3 x i32> %a, <3 x i32> %b) { | |
| ; CHECK-SD-LABEL: sadd_v3i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: add v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v1.4s, v2.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v3i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: add v3.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: cmgt v4.4s, v0.4s, v3.4s | |
| ; CHECK-GI-NEXT: cmgt v1.4s, v2.4s, v1.4s | |
| ; CHECK-GI-NEXT: movi v2.2d, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v4.16b | |
| ; CHECK-GI-NEXT: shl v1.4s, v1.4s, #31 | |
| ; CHECK-GI-NEXT: cmlt v1.4s, v1.4s, #0 | |
| ; CHECK-GI-NEXT: eor v2.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: and v1.16b, v3.16b, v1.16b | |
| ; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: orr v0.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i32>, <3 x i1>} @llvm.sadd.with.overflow(<3 x i32> %a, <3 x i32> %b) | |
| %e0 = extractvalue {<3 x i32>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i32>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i32> %e0, <3 x i32> %a | |
| ret <3 x i32> %r | |
| } | |
| define <3 x i32> @usub_v3i32(<3 x i32> %a, <3 x i32> %b) { | |
| ; CHECK-SD-LABEL: usub_v3i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmhi v2.4s, v1.4s, v0.4s | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v3i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.2d, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: cmhi v3.4s, v1.4s, v0.4s | |
| ; CHECK-GI-NEXT: sub v1.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: and v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: eor v2.16b, v3.16b, v2.16b | |
| ; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: orr v0.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i32>, <3 x i1>} @llvm.usub.with.overflow(<3 x i32> %a, <3 x i32> %b) | |
| %e0 = extractvalue {<3 x i32>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i32>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i32> %e0, <3 x i32> %a | |
| ret <3 x i32> %r | |
| } | |
| define <3 x i32> @ssub_v3i32(<3 x i32> %a, <3 x i32> %b) { | |
| ; CHECK-SD-LABEL: ssub_v3i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: sub v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v1.4s, v2.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v3i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: sub v3.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: cmgt v1.4s, v1.4s, v0.4s | |
| ; CHECK-GI-NEXT: cmgt v2.4s, v2.4s, v3.4s | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: movi v2.2d, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: shl v1.4s, v1.4s, #31 | |
| ; CHECK-GI-NEXT: cmlt v1.4s, v1.4s, #0 | |
| ; CHECK-GI-NEXT: eor v2.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: and v1.16b, v3.16b, v1.16b | |
| ; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b | |
| ; CHECK-GI-NEXT: orr v0.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i32>, <3 x i1>} @llvm.ssub.with.overflow(<3 x i32> %a, <3 x i32> %b) | |
| %e0 = extractvalue {<3 x i32>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i32>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i32> %e0, <3 x i32> %a | |
| ret <3 x i32> %r | |
| } | |
| define <3 x i32> @umul_v3i32(<3 x i32> %a, <3 x i32> %b) { | |
| ; CHECK-SD-LABEL: umul_v3i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull2 v2.2d, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: umull v3.2d, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: uzp2 v2.4s, v3.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v2.4s, #0 | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v3i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: mov v3.s[0], v0.s[0] | |
| ; CHECK-GI-NEXT: mov v4.s[0], v1.s[0] | |
| ; CHECK-GI-NEXT: mov w8, v0.s[2] | |
| ; CHECK-GI-NEXT: mov w9, v1.s[2] | |
| ; CHECK-GI-NEXT: movi v2.2d, #0000000000000000 | |
| ; CHECK-GI-NEXT: mov v3.s[1], v0.s[1] | |
| ; CHECK-GI-NEXT: mov v4.s[1], v1.s[1] | |
| ; CHECK-GI-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: umull x8, w8, w9 | |
| ; CHECK-GI-NEXT: umull v3.2d, v3.2s, v4.2s | |
| ; CHECK-GI-NEXT: lsr x8, x8, #32 | |
| ; CHECK-GI-NEXT: ushr v3.2d, v3.2d, #32 | |
| ; CHECK-GI-NEXT: mov d4, v3.d[1] | |
| ; CHECK-GI-NEXT: fmov x10, d3 | |
| ; CHECK-GI-NEXT: fmov s3, w10 | |
| ; CHECK-GI-NEXT: fmov x9, d4 | |
| ; CHECK-GI-NEXT: mov v3.s[1], w9 | |
| ; CHECK-GI-NEXT: mov v3.s[2], w8 | |
| ; CHECK-GI-NEXT: cmeq v2.4s, v3.4s, v2.4s | |
| ; CHECK-GI-NEXT: movi v3.2d, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: mvn v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bic v1.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: eor v3.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: and v0.16b, v0.16b, v3.16b | |
| ; CHECK-GI-NEXT: orr v0.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i32>, <3 x i1>} @llvm.umul.with.overflow(<3 x i32> %a, <3 x i32> %b) | |
| %e0 = extractvalue {<3 x i32>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i32>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i32> %e0, <3 x i32> %a | |
| ret <3 x i32> %r | |
| } | |
| define <3 x i32> @smul_v3i32(<3 x i32> %a, <3 x i32> %b) { | |
| ; CHECK-SD-LABEL: smul_v3i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull2 v2.2d, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: smull v3.2d, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: uzp2 v2.4s, v3.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmlt v3.4s, v1.4s, #0 | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v2.4s, v3.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v3i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: mov v3.s[0], v0.s[0] | |
| ; CHECK-GI-NEXT: mov v4.s[0], v1.s[0] | |
| ; CHECK-GI-NEXT: mov w8, v0.s[2] | |
| ; CHECK-GI-NEXT: mov w9, v1.s[2] | |
| ; CHECK-GI-NEXT: movi v2.4s, #95 | |
| ; CHECK-GI-NEXT: mov v3.s[1], v0.s[1] | |
| ; CHECK-GI-NEXT: mov v4.s[1], v1.s[1] | |
| ; CHECK-GI-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: smull x8, w8, w9 | |
| ; CHECK-GI-NEXT: neg v2.4s, v2.4s | |
| ; CHECK-GI-NEXT: smull v3.2d, v3.2s, v4.2s | |
| ; CHECK-GI-NEXT: asr x8, x8, #32 | |
| ; CHECK-GI-NEXT: sshl v2.4s, v1.4s, v2.4s | |
| ; CHECK-GI-NEXT: sshr v3.2d, v3.2d, #32 | |
| ; CHECK-GI-NEXT: mov d4, v3.d[1] | |
| ; CHECK-GI-NEXT: fmov x10, d3 | |
| ; CHECK-GI-NEXT: fmov s3, w10 | |
| ; CHECK-GI-NEXT: fmov x9, d4 | |
| ; CHECK-GI-NEXT: mov v3.s[1], w9 | |
| ; CHECK-GI-NEXT: mov v3.s[2], w8 | |
| ; CHECK-GI-NEXT: cmeq v2.4s, v3.4s, v2.4s | |
| ; CHECK-GI-NEXT: movi v3.2d, #0xffffffffffffffff | |
| ; CHECK-GI-NEXT: mvn v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bic v1.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: eor v3.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: and v0.16b, v0.16b, v3.16b | |
| ; CHECK-GI-NEXT: orr v0.16b, v1.16b, v0.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i32>, <3 x i1>} @llvm.smul.with.overflow(<3 x i32> %a, <3 x i32> %b) | |
| %e0 = extractvalue {<3 x i32>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i32>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i32> %e0, <3 x i32> %a | |
| ret <3 x i32> %r | |
| } | |
| define <4 x i32> @uadd_v4i32(<4 x i32> %a, <4 x i32> %b) { | |
| ; CHECK-SD-LABEL: uadd_v4i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmhi v2.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v4i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: cmhi v1.4s, v1.4s, v2.4s | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i32>, <4 x i1>} @llvm.uadd.with.overflow(<4 x i32> %a, <4 x i32> %b) | |
| %e0 = extractvalue {<4 x i32>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i32>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i32> %e0, <4 x i32> %a | |
| ret <4 x i32> %r | |
| } | |
| define <4 x i32> @sadd_v4i32(<4 x i32> %a, <4 x i32> %b) { | |
| ; CHECK-SD-LABEL: sadd_v4i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: add v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v1.4s, v2.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v4i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: cmlt v1.4s, v1.4s, #0 | |
| ; CHECK-GI-NEXT: cmgt v3.4s, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i32>, <4 x i1>} @llvm.sadd.with.overflow(<4 x i32> %a, <4 x i32> %b) | |
| %e0 = extractvalue {<4 x i32>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i32>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i32> %e0, <4 x i32> %a | |
| ret <4 x i32> %r | |
| } | |
| define <4 x i32> @usub_v4i32(<4 x i32> %a, <4 x i32> %b) { | |
| ; CHECK-SD-LABEL: usub_v4i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmhi v2.4s, v1.4s, v0.4s | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v4i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: cmhi v1.4s, v1.4s, v0.4s | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i32>, <4 x i1>} @llvm.usub.with.overflow(<4 x i32> %a, <4 x i32> %b) | |
| %e0 = extractvalue {<4 x i32>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i32>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i32> %e0, <4 x i32> %a | |
| ret <4 x i32> %r | |
| } | |
| define <4 x i32> @ssub_v4i32(<4 x i32> %a, <4 x i32> %b) { | |
| ; CHECK-SD-LABEL: ssub_v4i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: sub v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v1.4s, v2.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v4i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: cmgt v1.4s, v1.4s, v0.4s | |
| ; CHECK-GI-NEXT: cmlt v3.4s, v2.4s, #0 | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i32>, <4 x i1>} @llvm.ssub.with.overflow(<4 x i32> %a, <4 x i32> %b) | |
| %e0 = extractvalue {<4 x i32>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i32>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i32> %e0, <4 x i32> %a | |
| ret <4 x i32> %r | |
| } | |
| define <4 x i32> @umul_v4i32(<4 x i32> %a, <4 x i32> %b) { | |
| ; CHECK-SD-LABEL: umul_v4i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull2 v2.2d, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: umull v3.2d, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: uzp2 v2.4s, v3.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v2.4s, #0 | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v4i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull2 v2.2d, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: umull v3.2d, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: uzp2 v2.4s, v3.4s, v2.4s | |
| ; CHECK-GI-NEXT: cmtst v2.4s, v2.4s, v2.4s | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i32>, <4 x i1>} @llvm.umul.with.overflow(<4 x i32> %a, <4 x i32> %b) | |
| %e0 = extractvalue {<4 x i32>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i32>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i32> %e0, <4 x i32> %a | |
| ret <4 x i32> %r | |
| } | |
| define <4 x i32> @smul_v4i32(<4 x i32> %a, <4 x i32> %b) { | |
| ; CHECK-SD-LABEL: smul_v4i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull2 v2.2d, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: smull v3.2d, v0.2s, v1.2s | |
| ; CHECK-SD-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-SD-NEXT: uzp2 v2.4s, v3.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmlt v3.4s, v1.4s, #0 | |
| ; CHECK-SD-NEXT: cmeq v2.4s, v2.4s, v3.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v4i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v2.4s, #127 | |
| ; CHECK-GI-NEXT: smull2 v3.2d, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: smull v4.2d, v0.2s, v1.2s | |
| ; CHECK-GI-NEXT: mul v1.4s, v0.4s, v1.4s | |
| ; CHECK-GI-NEXT: neg v2.4s, v2.4s | |
| ; CHECK-GI-NEXT: uzp2 v3.4s, v4.4s, v3.4s | |
| ; CHECK-GI-NEXT: sshl v2.4s, v1.4s, v2.4s | |
| ; CHECK-GI-NEXT: cmeq v2.4s, v3.4s, v2.4s | |
| ; CHECK-GI-NEXT: mvn v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i32>, <4 x i1>} @llvm.smul.with.overflow(<4 x i32> %a, <4 x i32> %b) | |
| %e0 = extractvalue {<4 x i32>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i32>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i32> %e0, <4 x i32> %a | |
| ret <4 x i32> %r | |
| } | |
| define <8 x i32> @uadd_v8i32(<8 x i32> %a, <8 x i32> %b) { | |
| ; CHECK-SD-LABEL: uadd_v8i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v3.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: add v2.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmhi v4.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: cmhi v5.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v8i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v4.4s, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: add v5.4s, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: cmhi v2.4s, v2.4s, v4.4s | |
| ; CHECK-GI-NEXT: cmhi v3.4s, v3.4s, v5.4s | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i32>, <8 x i1>} @llvm.uadd.with.overflow(<8 x i32> %a, <8 x i32> %b) | |
| %e0 = extractvalue {<8 x i32>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i32>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i32> %e0, <8 x i32> %a | |
| ret <8 x i32> %r | |
| } | |
| define <8 x i32> @sadd_v8i32(<8 x i32> %a, <8 x i32> %b) { | |
| ; CHECK-SD-LABEL: sadd_v8i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v4.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: sqadd v5.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: add v3.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: add v2.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmeq v4.4s, v3.4s, v4.4s | |
| ; CHECK-SD-NEXT: cmeq v5.4s, v2.4s, v5.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v8i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v4.4s, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: add v5.4s, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: cmlt v2.4s, v2.4s, #0 | |
| ; CHECK-GI-NEXT: cmlt v3.4s, v3.4s, #0 | |
| ; CHECK-GI-NEXT: cmgt v6.4s, v0.4s, v4.4s | |
| ; CHECK-GI-NEXT: cmgt v7.4s, v1.4s, v5.4s | |
| ; CHECK-GI-NEXT: uzp1 v2.8h, v2.8h, v3.8h | |
| ; CHECK-GI-NEXT: uzp1 v3.8h, v6.8h, v7.8h | |
| ; CHECK-GI-NEXT: eor v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: sshll v3.4s, v2.4h, #0 | |
| ; CHECK-GI-NEXT: sshll2 v2.4s, v2.8h, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i32>, <8 x i1>} @llvm.sadd.with.overflow(<8 x i32> %a, <8 x i32> %b) | |
| %e0 = extractvalue {<8 x i32>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i32>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i32> %e0, <8 x i32> %a | |
| ret <8 x i32> %r | |
| } | |
| define <8 x i32> @usub_v8i32(<8 x i32> %a, <8 x i32> %b) { | |
| ; CHECK-SD-LABEL: usub_v8i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v3.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: sub v2.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmhi v4.4s, v3.4s, v1.4s | |
| ; CHECK-SD-NEXT: cmhi v5.4s, v2.4s, v0.4s | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v8i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v4.4s, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: sub v5.4s, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: cmhi v2.4s, v2.4s, v0.4s | |
| ; CHECK-GI-NEXT: cmhi v3.4s, v3.4s, v1.4s | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i32>, <8 x i1>} @llvm.usub.with.overflow(<8 x i32> %a, <8 x i32> %b) | |
| %e0 = extractvalue {<8 x i32>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i32>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i32> %e0, <8 x i32> %a | |
| ret <8 x i32> %r | |
| } | |
| define <8 x i32> @ssub_v8i32(<8 x i32> %a, <8 x i32> %b) { | |
| ; CHECK-SD-LABEL: ssub_v8i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v4.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: sqsub v5.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: sub v3.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: sub v2.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: cmeq v4.4s, v3.4s, v4.4s | |
| ; CHECK-SD-NEXT: cmeq v5.4s, v2.4s, v5.4s | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v8i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v4.4s, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: sub v5.4s, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: cmgt v2.4s, v2.4s, v0.4s | |
| ; CHECK-GI-NEXT: cmgt v3.4s, v3.4s, v1.4s | |
| ; CHECK-GI-NEXT: cmlt v6.4s, v4.4s, #0 | |
| ; CHECK-GI-NEXT: cmlt v7.4s, v5.4s, #0 | |
| ; CHECK-GI-NEXT: uzp1 v2.8h, v2.8h, v3.8h | |
| ; CHECK-GI-NEXT: uzp1 v3.8h, v6.8h, v7.8h | |
| ; CHECK-GI-NEXT: eor v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: sshll v3.4s, v2.4h, #0 | |
| ; CHECK-GI-NEXT: sshll2 v2.4s, v2.8h, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i32>, <8 x i1>} @llvm.ssub.with.overflow(<8 x i32> %a, <8 x i32> %b) | |
| %e0 = extractvalue {<8 x i32>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i32>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i32> %e0, <8 x i32> %a | |
| ret <8 x i32> %r | |
| } | |
| define <8 x i32> @umul_v8i32(<8 x i32> %a, <8 x i32> %b) { | |
| ; CHECK-SD-LABEL: umul_v8i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: umull2 v4.2d, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: umull v5.2d, v1.2s, v3.2s | |
| ; CHECK-SD-NEXT: umull2 v6.2d, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: umull v7.2d, v0.2s, v2.2s | |
| ; CHECK-SD-NEXT: mul v3.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: mul v2.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: uzp2 v4.4s, v5.4s, v4.4s | |
| ; CHECK-SD-NEXT: uzp2 v5.4s, v7.4s, v6.4s | |
| ; CHECK-SD-NEXT: cmeq v4.4s, v4.4s, #0 | |
| ; CHECK-SD-NEXT: cmeq v5.4s, v5.4s, #0 | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v8i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: umull v4.2d, v0.2s, v2.2s | |
| ; CHECK-GI-NEXT: umull2 v5.2d, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: umull v6.2d, v1.2s, v3.2s | |
| ; CHECK-GI-NEXT: umull2 v7.2d, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: mul v2.4s, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: mul v3.4s, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: uzp2 v4.4s, v4.4s, v5.4s | |
| ; CHECK-GI-NEXT: uzp2 v5.4s, v6.4s, v7.4s | |
| ; CHECK-GI-NEXT: cmtst v4.4s, v4.4s, v4.4s | |
| ; CHECK-GI-NEXT: cmtst v5.4s, v5.4s, v5.4s | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v4.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v3.16b, v5.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i32>, <8 x i1>} @llvm.umul.with.overflow(<8 x i32> %a, <8 x i32> %b) | |
| %e0 = extractvalue {<8 x i32>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i32>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i32> %e0, <8 x i32> %a | |
| ret <8 x i32> %r | |
| } | |
| define <8 x i32> @smul_v8i32(<8 x i32> %a, <8 x i32> %b) { | |
| ; CHECK-SD-LABEL: smul_v8i32: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: smull2 v4.2d, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: smull v5.2d, v1.2s, v3.2s | |
| ; CHECK-SD-NEXT: smull2 v6.2d, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: smull v7.2d, v0.2s, v2.2s | |
| ; CHECK-SD-NEXT: mul v3.4s, v1.4s, v3.4s | |
| ; CHECK-SD-NEXT: mul v2.4s, v0.4s, v2.4s | |
| ; CHECK-SD-NEXT: uzp2 v4.4s, v5.4s, v4.4s | |
| ; CHECK-SD-NEXT: uzp2 v5.4s, v7.4s, v6.4s | |
| ; CHECK-SD-NEXT: cmlt v6.4s, v3.4s, #0 | |
| ; CHECK-SD-NEXT: cmlt v7.4s, v2.4s, #0 | |
| ; CHECK-SD-NEXT: cmeq v4.4s, v4.4s, v6.4s | |
| ; CHECK-SD-NEXT: cmeq v5.4s, v5.4s, v7.4s | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v8i32: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: movi v4.2d, #0x0000ff000000ff | |
| ; CHECK-GI-NEXT: smull v5.2d, v0.2s, v2.2s | |
| ; CHECK-GI-NEXT: smull v6.2d, v1.2s, v3.2s | |
| ; CHECK-GI-NEXT: smull2 v7.2d, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: mul v2.4s, v0.4s, v2.4s | |
| ; CHECK-GI-NEXT: smull2 v16.2d, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: mul v3.4s, v1.4s, v3.4s | |
| ; CHECK-GI-NEXT: neg v4.4s, v4.4s | |
| ; CHECK-GI-NEXT: shrn v5.2s, v5.2d, #32 | |
| ; CHECK-GI-NEXT: shrn v6.2s, v6.2d, #32 | |
| ; CHECK-GI-NEXT: sshl v17.4s, v2.4s, v4.4s | |
| ; CHECK-GI-NEXT: sshl v4.4s, v3.4s, v4.4s | |
| ; CHECK-GI-NEXT: shrn2 v5.4s, v7.2d, #32 | |
| ; CHECK-GI-NEXT: shrn2 v6.4s, v16.2d, #32 | |
| ; CHECK-GI-NEXT: cmeq v5.4s, v5.4s, v17.4s | |
| ; CHECK-GI-NEXT: cmeq v4.4s, v6.4s, v4.4s | |
| ; CHECK-GI-NEXT: mvn v5.16b, v5.16b | |
| ; CHECK-GI-NEXT: mvn v4.16b, v4.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<8 x i32>, <8 x i1>} @llvm.smul.with.overflow(<8 x i32> %a, <8 x i32> %b) | |
| %e0 = extractvalue {<8 x i32>, <8 x i1>} %o, 0 | |
| %e1 = extractvalue {<8 x i32>, <8 x i1>} %o, 1 | |
| %r = select <8 x i1> %e1, <8 x i32> %e0, <8 x i32> %a | |
| ret <8 x i32> %r | |
| } | |
| define <2 x i64> @uadd_v2i64(<2 x i64> %a, <2 x i64> %b) { | |
| ; CHECK-SD-LABEL: uadd_v2i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v1.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: cmhi v2.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v2i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.2d, v0.2d, v1.2d | |
| ; CHECK-GI-NEXT: cmhi v1.2d, v1.2d, v2.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow(<2 x i64> %a, <2 x i64> %b) | |
| %e0 = extractvalue {<2 x i64>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i64>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i64> %e0, <2 x i64> %a | |
| ret <2 x i64> %r | |
| } | |
| define <2 x i64> @sadd_v2i64(<2 x i64> %a, <2 x i64> %b) { | |
| ; CHECK-SD-LABEL: sadd_v2i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v2.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: add v1.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: cmeq v2.2d, v1.2d, v2.2d | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v2i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v2.2d, v0.2d, v1.2d | |
| ; CHECK-GI-NEXT: cmlt v1.2d, v1.2d, #0 | |
| ; CHECK-GI-NEXT: cmgt v3.2d, v0.2d, v2.2d | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow(<2 x i64> %a, <2 x i64> %b) | |
| %e0 = extractvalue {<2 x i64>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i64>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i64> %e0, <2 x i64> %a | |
| ret <2 x i64> %r | |
| } | |
| define <2 x i64> @usub_v2i64(<2 x i64> %a, <2 x i64> %b) { | |
| ; CHECK-SD-LABEL: usub_v2i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v1.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: cmhi v2.2d, v1.2d, v0.2d | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v2i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.2d, v0.2d, v1.2d | |
| ; CHECK-GI-NEXT: cmhi v1.2d, v1.2d, v0.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow(<2 x i64> %a, <2 x i64> %b) | |
| %e0 = extractvalue {<2 x i64>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i64>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i64> %e0, <2 x i64> %a | |
| ret <2 x i64> %r | |
| } | |
| define <2 x i64> @ssub_v2i64(<2 x i64> %a, <2 x i64> %b) { | |
| ; CHECK-SD-LABEL: ssub_v2i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v2.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: sub v1.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: cmeq v2.2d, v1.2d, v2.2d | |
| ; CHECK-SD-NEXT: bif v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v2i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v2.2d, v0.2d, v1.2d | |
| ; CHECK-GI-NEXT: cmgt v1.2d, v1.2d, v0.2d | |
| ; CHECK-GI-NEXT: cmlt v3.2d, v2.2d, #0 | |
| ; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow(<2 x i64> %a, <2 x i64> %b) | |
| %e0 = extractvalue {<2 x i64>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i64>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i64> %e0, <2 x i64> %a | |
| ret <2 x i64> %r | |
| } | |
| define <2 x i64> @umul_v2i64(<2 x i64> %a, <2 x i64> %b) { | |
| ; CHECK-SD-LABEL: umul_v2i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: mov x8, v1.d[1] | |
| ; CHECK-SD-NEXT: mov x9, v0.d[1] | |
| ; CHECK-SD-NEXT: fmov x11, d1 | |
| ; CHECK-SD-NEXT: fmov x12, d0 | |
| ; CHECK-SD-NEXT: umulh x10, x9, x8 | |
| ; CHECK-SD-NEXT: umulh x13, x12, x11 | |
| ; CHECK-SD-NEXT: mul x11, x12, x11 | |
| ; CHECK-SD-NEXT: cmp xzr, x10 | |
| ; CHECK-SD-NEXT: mul x8, x9, x8 | |
| ; CHECK-SD-NEXT: csetm x9, ne | |
| ; CHECK-SD-NEXT: cmp xzr, x13 | |
| ; CHECK-SD-NEXT: csetm x10, ne | |
| ; CHECK-SD-NEXT: fmov d1, x11 | |
| ; CHECK-SD-NEXT: fmov d2, x10 | |
| ; CHECK-SD-NEXT: mov v1.d[1], x8 | |
| ; CHECK-SD-NEXT: mov v2.d[1], x9 | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v2i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: fmov x10, d0 | |
| ; CHECK-GI-NEXT: fmov x11, d1 | |
| ; CHECK-GI-NEXT: mov x8, v0.d[1] | |
| ; CHECK-GI-NEXT: mov x9, v1.d[1] | |
| ; CHECK-GI-NEXT: umulh x12, x10, x11 | |
| ; CHECK-GI-NEXT: umulh x13, x8, x9 | |
| ; CHECK-GI-NEXT: mul x10, x10, x11 | |
| ; CHECK-GI-NEXT: fmov d1, x12 | |
| ; CHECK-GI-NEXT: mul x8, x8, x9 | |
| ; CHECK-GI-NEXT: mov v1.d[1], x13 | |
| ; CHECK-GI-NEXT: fmov d2, x10 | |
| ; CHECK-GI-NEXT: mov v2.d[1], x8 | |
| ; CHECK-GI-NEXT: cmtst v1.2d, v1.2d, v1.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i64>, <2 x i1>} @llvm.umul.with.overflow(<2 x i64> %a, <2 x i64> %b) | |
| %e0 = extractvalue {<2 x i64>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i64>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i64> %e0, <2 x i64> %a | |
| ret <2 x i64> %r | |
| } | |
| define <2 x i64> @smul_v2i64(<2 x i64> %a, <2 x i64> %b) { | |
| ; CHECK-SD-LABEL: smul_v2i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: mov x8, v1.d[1] | |
| ; CHECK-SD-NEXT: mov x9, v0.d[1] | |
| ; CHECK-SD-NEXT: fmov x11, d0 | |
| ; CHECK-SD-NEXT: mul x10, x9, x8 | |
| ; CHECK-SD-NEXT: smulh x8, x9, x8 | |
| ; CHECK-SD-NEXT: fmov x9, d1 | |
| ; CHECK-SD-NEXT: mul x12, x11, x9 | |
| ; CHECK-SD-NEXT: smulh x9, x11, x9 | |
| ; CHECK-SD-NEXT: cmp x8, x10, asr #63 | |
| ; CHECK-SD-NEXT: csetm x8, ne | |
| ; CHECK-SD-NEXT: fmov d2, x12 | |
| ; CHECK-SD-NEXT: cmp x9, x12, asr #63 | |
| ; CHECK-SD-NEXT: csetm x9, ne | |
| ; CHECK-SD-NEXT: mov v2.d[1], x10 | |
| ; CHECK-SD-NEXT: fmov d1, x9 | |
| ; CHECK-SD-NEXT: mov v1.d[1], x8 | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v1.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v2i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: fmov x9, d0 | |
| ; CHECK-GI-NEXT: fmov x10, d1 | |
| ; CHECK-GI-NEXT: adrp x8, .LCPI95_0 | |
| ; CHECK-GI-NEXT: mov d2, v1.d[1] | |
| ; CHECK-GI-NEXT: mov d3, v0.d[1] | |
| ; CHECK-GI-NEXT: mov x13, v1.d[1] | |
| ; CHECK-GI-NEXT: mov x14, v0.d[1] | |
| ; CHECK-GI-NEXT: umulh x11, x9, x10 | |
| ; CHECK-GI-NEXT: asr x12, x10, #63 | |
| ; CHECK-GI-NEXT: fmov x15, d2 | |
| ; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI95_0] | |
| ; CHECK-GI-NEXT: madd x11, x9, x12, x11 | |
| ; CHECK-GI-NEXT: fmov x12, d3 | |
| ; CHECK-GI-NEXT: neg v2.2d, v2.2d | |
| ; CHECK-GI-NEXT: mul x13, x14, x13 | |
| ; CHECK-GI-NEXT: asr x14, x15, #63 | |
| ; CHECK-GI-NEXT: umulh x16, x12, x15 | |
| ; CHECK-GI-NEXT: madd x14, x12, x14, x16 | |
| ; CHECK-GI-NEXT: asr x16, x9, #63 | |
| ; CHECK-GI-NEXT: asr x12, x12, #63 | |
| ; CHECK-GI-NEXT: mul x9, x9, x10 | |
| ; CHECK-GI-NEXT: madd x10, x16, x10, x11 | |
| ; CHECK-GI-NEXT: madd x11, x12, x15, x14 | |
| ; CHECK-GI-NEXT: fmov d1, x9 | |
| ; CHECK-GI-NEXT: fmov d3, x10 | |
| ; CHECK-GI-NEXT: mov v1.d[1], x13 | |
| ; CHECK-GI-NEXT: mov v3.d[1], x11 | |
| ; CHECK-GI-NEXT: sshl v2.2d, v1.2d, v2.2d | |
| ; CHECK-GI-NEXT: cmeq v2.2d, v3.2d, v2.2d | |
| ; CHECK-GI-NEXT: mvn v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i64>, <2 x i1>} @llvm.smul.with.overflow(<2 x i64> %a, <2 x i64> %b) | |
| %e0 = extractvalue {<2 x i64>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i64>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i64> %e0, <2 x i64> %a | |
| ret <2 x i64> %r | |
| } | |
| define <3 x i64> @uadd_v3i64(<3 x i64> %a, <3 x i64> %b) { | |
| ; CHECK-SD-LABEL: uadd_v3i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-SD-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-SD-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-SD-NEXT: add d4, d2, d5 | |
| ; CHECK-SD-NEXT: add v1.2d, v0.2d, v3.2d | |
| ; CHECK-SD-NEXT: cmhi v3.2d, v0.2d, v1.2d | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: cmhi v1.2d, v2.2d, v4.2d | |
| ; CHECK-SD-NEXT: bit v2.16b, v4.16b, v1.16b | |
| ; CHECK-SD-NEXT: mov d1, v0.d[1] | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2 | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v3i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-GI-NEXT: mov v6.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v7.16b, v3.16b | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-GI-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-GI-NEXT: fmov x8, d2 | |
| ; CHECK-GI-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: fmov x9, d5 | |
| ; CHECK-GI-NEXT: mov v6.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: mov v7.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: add x9, x8, x9 | |
| ; CHECK-GI-NEXT: add v4.2d, v6.2d, v7.2d | |
| ; CHECK-GI-NEXT: cmhi v1.2d, v3.2d, v4.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v1.16b | |
| ; CHECK-GI-NEXT: fmov d1, x9 | |
| ; CHECK-GI-NEXT: cmhi v2.2d, v5.2d, v1.2d | |
| ; CHECK-GI-NEXT: mov d1, v0.d[1] | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-GI-NEXT: fmov x10, d2 | |
| ; CHECK-GI-NEXT: and x9, x9, x10 | |
| ; CHECK-GI-NEXT: bic x8, x8, x10 | |
| ; CHECK-GI-NEXT: orr x8, x9, x8 | |
| ; CHECK-GI-NEXT: fmov d2, x8 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i64>, <3 x i1>} @llvm.uadd.with.overflow(<3 x i64> %a, <3 x i64> %b) | |
| %e0 = extractvalue {<3 x i64>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i64>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i64> %e0, <3 x i64> %a | |
| ret <3 x i64> %r | |
| } | |
| define <3 x i64> @sadd_v3i64(<3 x i64> %a, <3 x i64> %b) { | |
| ; CHECK-SD-LABEL: sadd_v3i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-SD-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-SD-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-SD-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-SD-NEXT: sqadd v4.2d, v2.2d, v5.2d | |
| ; CHECK-SD-NEXT: add v5.2d, v2.2d, v5.2d | |
| ; CHECK-SD-NEXT: sqadd v1.2d, v0.2d, v3.2d | |
| ; CHECK-SD-NEXT: add v3.2d, v0.2d, v3.2d | |
| ; CHECK-SD-NEXT: cmeq v1.2d, v3.2d, v1.2d | |
| ; CHECK-SD-NEXT: bif v0.16b, v3.16b, v1.16b | |
| ; CHECK-SD-NEXT: cmeq v1.2d, v5.2d, v4.2d | |
| ; CHECK-SD-NEXT: bif v2.16b, v5.16b, v1.16b | |
| ; CHECK-SD-NEXT: mov d1, v0.d[1] | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2 | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v3i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-GI-NEXT: mov v7.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v16.16b, v3.16b | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-GI-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-GI-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-GI-NEXT: mov v17.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: fmov x10, d2 | |
| ; CHECK-GI-NEXT: fmov x11, d5 | |
| ; CHECK-GI-NEXT: movi d6, #0000000000000000 | |
| ; CHECK-GI-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: mov v7.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: mov v16.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: mov v17.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: add x11, x10, x11 | |
| ; CHECK-GI-NEXT: cmlt v3.2d, v3.2d, #0 | |
| ; CHECK-GI-NEXT: cmgt v5.2d, v6.2d, v5.2d | |
| ; CHECK-GI-NEXT: add v4.2d, v7.2d, v16.2d | |
| ; CHECK-GI-NEXT: fmov d16, x11 | |
| ; CHECK-GI-NEXT: fmov x12, d3 | |
| ; CHECK-GI-NEXT: mov x8, v3.d[1] | |
| ; CHECK-GI-NEXT: cmgt v7.2d, v17.2d, v4.2d | |
| ; CHECK-GI-NEXT: cmgt v2.2d, v2.2d, v16.2d | |
| ; CHECK-GI-NEXT: fmov s3, w12 | |
| ; CHECK-GI-NEXT: fmov x13, d7 | |
| ; CHECK-GI-NEXT: mov x9, v7.d[1] | |
| ; CHECK-GI-NEXT: mov v3.h[1], w8 | |
| ; CHECK-GI-NEXT: fmov s7, w13 | |
| ; CHECK-GI-NEXT: mov v3.h[2], v5.h[0] | |
| ; CHECK-GI-NEXT: mov v7.h[1], w9 | |
| ; CHECK-GI-NEXT: mov v7.h[2], v2.h[0] | |
| ; CHECK-GI-NEXT: eor v2.8b, v3.8b, v7.8b | |
| ; CHECK-GI-NEXT: zip1 v3.4h, v2.4h, v2.4h | |
| ; CHECK-GI-NEXT: smov x8, v2.h[2] | |
| ; CHECK-GI-NEXT: ushll v3.2d, v3.2s, #0 | |
| ; CHECK-GI-NEXT: and x9, x11, x8 | |
| ; CHECK-GI-NEXT: bic x8, x10, x8 | |
| ; CHECK-GI-NEXT: orr x8, x9, x8 | |
| ; CHECK-GI-NEXT: fmov d2, x8 | |
| ; CHECK-GI-NEXT: shl v3.2d, v3.2d, #63 | |
| ; CHECK-GI-NEXT: cmlt v1.2d, v3.2d, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v1.16b | |
| ; CHECK-GI-NEXT: mov d1, v0.d[1] | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i64>, <3 x i1>} @llvm.sadd.with.overflow(<3 x i64> %a, <3 x i64> %b) | |
| %e0 = extractvalue {<3 x i64>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i64>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i64> %e0, <3 x i64> %a | |
| ret <3 x i64> %r | |
| } | |
| define <3 x i64> @usub_v3i64(<3 x i64> %a, <3 x i64> %b) { | |
| ; CHECK-SD-LABEL: usub_v3i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-SD-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-SD-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-SD-NEXT: sub d4, d2, d5 | |
| ; CHECK-SD-NEXT: sub v1.2d, v0.2d, v3.2d | |
| ; CHECK-SD-NEXT: cmhi v3.2d, v1.2d, v0.2d | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: cmhi v1.2d, v4.2d, v2.2d | |
| ; CHECK-SD-NEXT: bit v2.16b, v4.16b, v1.16b | |
| ; CHECK-SD-NEXT: mov d1, v0.d[1] | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2 | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v3i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-GI-NEXT: mov v6.16b, v3.16b | |
| ; CHECK-GI-NEXT: mov v7.16b, v0.16b | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-GI-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-GI-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-GI-NEXT: mov v16.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: fmov x8, d2 | |
| ; CHECK-GI-NEXT: fmov x9, d5 | |
| ; CHECK-GI-NEXT: mov v6.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: mov v7.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: mov v16.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: sub x9, x8, x9 | |
| ; CHECK-GI-NEXT: sub v1.2d, v7.2d, v6.2d | |
| ; CHECK-GI-NEXT: cmhi v3.2d, v3.2d, v16.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v1.16b, v3.16b | |
| ; CHECK-GI-NEXT: cmhi v3.2d, v5.2d, v2.2d | |
| ; CHECK-GI-NEXT: fmov x10, d3 | |
| ; CHECK-GI-NEXT: mov d1, v0.d[1] | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-GI-NEXT: and x9, x9, x10 | |
| ; CHECK-GI-NEXT: bic x8, x8, x10 | |
| ; CHECK-GI-NEXT: orr x8, x9, x8 | |
| ; CHECK-GI-NEXT: fmov d2, x8 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i64>, <3 x i1>} @llvm.usub.with.overflow(<3 x i64> %a, <3 x i64> %b) | |
| %e0 = extractvalue {<3 x i64>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i64>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i64> %e0, <3 x i64> %a | |
| ret <3 x i64> %r | |
| } | |
| define <3 x i64> @ssub_v3i64(<3 x i64> %a, <3 x i64> %b) { | |
| ; CHECK-SD-LABEL: ssub_v3i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-SD-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-SD-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-SD-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-SD-NEXT: sqsub v4.2d, v2.2d, v5.2d | |
| ; CHECK-SD-NEXT: sub v5.2d, v2.2d, v5.2d | |
| ; CHECK-SD-NEXT: sqsub v1.2d, v0.2d, v3.2d | |
| ; CHECK-SD-NEXT: sub v3.2d, v0.2d, v3.2d | |
| ; CHECK-SD-NEXT: cmeq v1.2d, v3.2d, v1.2d | |
| ; CHECK-SD-NEXT: bif v0.16b, v3.16b, v1.16b | |
| ; CHECK-SD-NEXT: cmeq v1.2d, v5.2d, v4.2d | |
| ; CHECK-SD-NEXT: bif v2.16b, v5.16b, v1.16b | |
| ; CHECK-SD-NEXT: mov d1, v0.d[1] | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2 | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v3i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-GI-NEXT: mov v7.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v16.16b, v3.16b | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-GI-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-GI-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-GI-NEXT: mov v17.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: fmov x10, d2 | |
| ; CHECK-GI-NEXT: fmov x11, d5 | |
| ; CHECK-GI-NEXT: movi d6, #0000000000000000 | |
| ; CHECK-GI-NEXT: cmgt v2.2d, v5.2d, v2.2d | |
| ; CHECK-GI-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: mov v7.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: mov v16.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: mov v17.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: sub x11, x10, x11 | |
| ; CHECK-GI-NEXT: sub v4.2d, v7.2d, v16.2d | |
| ; CHECK-GI-NEXT: cmgt v3.2d, v3.2d, v17.2d | |
| ; CHECK-GI-NEXT: fmov d16, x11 | |
| ; CHECK-GI-NEXT: cmlt v7.2d, v4.2d, #0 | |
| ; CHECK-GI-NEXT: fmov x12, d3 | |
| ; CHECK-GI-NEXT: mov x8, v3.d[1] | |
| ; CHECK-GI-NEXT: cmgt v5.2d, v6.2d, v16.2d | |
| ; CHECK-GI-NEXT: fmov x13, d7 | |
| ; CHECK-GI-NEXT: mov x9, v7.d[1] | |
| ; CHECK-GI-NEXT: fmov s3, w12 | |
| ; CHECK-GI-NEXT: fmov s7, w13 | |
| ; CHECK-GI-NEXT: mov v3.h[1], w8 | |
| ; CHECK-GI-NEXT: mov v7.h[1], w9 | |
| ; CHECK-GI-NEXT: mov v3.h[2], v2.h[0] | |
| ; CHECK-GI-NEXT: mov v7.h[2], v5.h[0] | |
| ; CHECK-GI-NEXT: eor v2.8b, v3.8b, v7.8b | |
| ; CHECK-GI-NEXT: zip1 v3.4h, v2.4h, v2.4h | |
| ; CHECK-GI-NEXT: smov x8, v2.h[2] | |
| ; CHECK-GI-NEXT: ushll v3.2d, v3.2s, #0 | |
| ; CHECK-GI-NEXT: and x9, x11, x8 | |
| ; CHECK-GI-NEXT: bic x8, x10, x8 | |
| ; CHECK-GI-NEXT: orr x8, x9, x8 | |
| ; CHECK-GI-NEXT: fmov d2, x8 | |
| ; CHECK-GI-NEXT: shl v3.2d, v3.2d, #63 | |
| ; CHECK-GI-NEXT: cmlt v1.2d, v3.2d, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v1.16b | |
| ; CHECK-GI-NEXT: mov d1, v0.d[1] | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i64>, <3 x i1>} @llvm.ssub.with.overflow(<3 x i64> %a, <3 x i64> %b) | |
| %e0 = extractvalue {<3 x i64>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i64>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i64> %e0, <3 x i64> %a | |
| ret <3 x i64> %r | |
| } | |
| define <3 x i64> @umul_v3i64(<3 x i64> %a, <3 x i64> %b) { | |
| ; CHECK-SD-LABEL: umul_v3i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-SD-NEXT: fmov x8, d4 | |
| ; CHECK-SD-NEXT: fmov x9, d1 | |
| ; CHECK-SD-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-SD-NEXT: fmov x11, d3 | |
| ; CHECK-SD-NEXT: fmov x12, d0 | |
| ; CHECK-SD-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-SD-NEXT: umulh x10, x9, x8 | |
| ; CHECK-SD-NEXT: umulh x13, x12, x11 | |
| ; CHECK-SD-NEXT: mul x11, x12, x11 | |
| ; CHECK-SD-NEXT: cmp xzr, x10 | |
| ; CHECK-SD-NEXT: fmov x10, d5 | |
| ; CHECK-SD-NEXT: mul x8, x9, x8 | |
| ; CHECK-SD-NEXT: csetm x9, ne | |
| ; CHECK-SD-NEXT: cmp xzr, x13 | |
| ; CHECK-SD-NEXT: fmov x13, d2 | |
| ; CHECK-SD-NEXT: csetm x12, ne | |
| ; CHECK-SD-NEXT: fmov d1, x11 | |
| ; CHECK-SD-NEXT: fmov d3, x12 | |
| ; CHECK-SD-NEXT: mov v1.d[1], x8 | |
| ; CHECK-SD-NEXT: umulh x8, x13, x10 | |
| ; CHECK-SD-NEXT: mov v3.d[1], x9 | |
| ; CHECK-SD-NEXT: mul x9, x13, x10 | |
| ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: cmp xzr, x8 | |
| ; CHECK-SD-NEXT: csetm x8, ne | |
| ; CHECK-SD-NEXT: fmov d1, x9 | |
| ; CHECK-SD-NEXT: fmov d3, x8 | |
| ; CHECK-SD-NEXT: bit v2.16b, v1.16b, v3.16b | |
| ; CHECK-SD-NEXT: mov d1, v0.d[1] | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2 | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v3i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-GI-NEXT: mov v16.16b, v3.16b | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: fmov x8, d0 | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-GI-NEXT: fmov x9, d3 | |
| ; CHECK-GI-NEXT: mov v7.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: fmov x10, d4 | |
| ; CHECK-GI-NEXT: movi d6, #0000000000000000 | |
| ; CHECK-GI-NEXT: mov v16.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: umulh x8, x8, x9 | |
| ; CHECK-GI-NEXT: fmov x9, d1 | |
| ; CHECK-GI-NEXT: mov v7.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: fmov x12, d0 | |
| ; CHECK-GI-NEXT: umulh x9, x9, x10 | |
| ; CHECK-GI-NEXT: mov x10, v0.d[1] | |
| ; CHECK-GI-NEXT: mov x11, v16.d[1] | |
| ; CHECK-GI-NEXT: fmov x13, d16 | |
| ; CHECK-GI-NEXT: fmov d0, x8 | |
| ; CHECK-GI-NEXT: fmov x8, d2 | |
| ; CHECK-GI-NEXT: mul x12, x12, x13 | |
| ; CHECK-GI-NEXT: mov v0.d[1], x9 | |
| ; CHECK-GI-NEXT: mul x10, x10, x11 | |
| ; CHECK-GI-NEXT: fmov x11, d5 | |
| ; CHECK-GI-NEXT: umulh x9, x8, x11 | |
| ; CHECK-GI-NEXT: fmov d2, x12 | |
| ; CHECK-GI-NEXT: cmtst v0.2d, v0.2d, v0.2d | |
| ; CHECK-GI-NEXT: mov v2.d[1], x10 | |
| ; CHECK-GI-NEXT: fmov d1, x9 | |
| ; CHECK-GI-NEXT: mul x9, x8, x11 | |
| ; CHECK-GI-NEXT: bsl v0.16b, v2.16b, v7.16b | |
| ; CHECK-GI-NEXT: cmeq v1.2d, v1.2d, v6.2d | |
| ; CHECK-GI-NEXT: mvn v2.16b, v1.16b | |
| ; CHECK-GI-NEXT: mov d1, v0.d[1] | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-GI-NEXT: fmov x10, d2 | |
| ; CHECK-GI-NEXT: and x9, x9, x10 | |
| ; CHECK-GI-NEXT: bic x8, x8, x10 | |
| ; CHECK-GI-NEXT: orr x8, x9, x8 | |
| ; CHECK-GI-NEXT: fmov d2, x8 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i64>, <3 x i1>} @llvm.umul.with.overflow(<3 x i64> %a, <3 x i64> %b) | |
| %e0 = extractvalue {<3 x i64>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i64>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i64> %e0, <3 x i64> %a | |
| ret <3 x i64> %r | |
| } | |
| define <3 x i64> @smul_v3i64(<3 x i64> %a, <3 x i64> %b) { | |
| ; CHECK-SD-LABEL: smul_v3i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-SD-NEXT: fmov x8, d4 | |
| ; CHECK-SD-NEXT: fmov x9, d1 | |
| ; CHECK-SD-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d5 killed $d5 def $q5 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2 | |
| ; CHECK-SD-NEXT: fmov x11, d0 | |
| ; CHECK-SD-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-SD-NEXT: mul x10, x9, x8 | |
| ; CHECK-SD-NEXT: smulh x8, x9, x8 | |
| ; CHECK-SD-NEXT: fmov x9, d3 | |
| ; CHECK-SD-NEXT: mul x12, x11, x9 | |
| ; CHECK-SD-NEXT: smulh x9, x11, x9 | |
| ; CHECK-SD-NEXT: cmp x8, x10, asr #63 | |
| ; CHECK-SD-NEXT: fmov x11, d5 | |
| ; CHECK-SD-NEXT: fmov x8, d2 | |
| ; CHECK-SD-NEXT: csetm x13, ne | |
| ; CHECK-SD-NEXT: fmov d3, x12 | |
| ; CHECK-SD-NEXT: mul x14, x8, x11 | |
| ; CHECK-SD-NEXT: cmp x9, x12, asr #63 | |
| ; CHECK-SD-NEXT: csetm x9, ne | |
| ; CHECK-SD-NEXT: smulh x8, x8, x11 | |
| ; CHECK-SD-NEXT: mov v3.d[1], x10 | |
| ; CHECK-SD-NEXT: fmov d1, x9 | |
| ; CHECK-SD-NEXT: mov v1.d[1], x13 | |
| ; CHECK-SD-NEXT: cmp x8, x14, asr #63 | |
| ; CHECK-SD-NEXT: csetm x8, ne | |
| ; CHECK-SD-NEXT: bit v0.16b, v3.16b, v1.16b | |
| ; CHECK-SD-NEXT: fmov d1, x8 | |
| ; CHECK-SD-NEXT: fmov d3, x14 | |
| ; CHECK-SD-NEXT: bit v2.16b, v3.16b, v1.16b | |
| ; CHECK-SD-NEXT: mov d1, v0.d[1] | |
| ; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2 | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v3i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0 | |
| ; CHECK-GI-NEXT: // kill: def $d3 killed $d3 def $q3 | |
| ; CHECK-GI-NEXT: fmov x8, d0 | |
| ; CHECK-GI-NEXT: fmov x9, d3 | |
| ; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1 | |
| ; CHECK-GI-NEXT: // kill: def $d4 killed $d4 def $q4 | |
| ; CHECK-GI-NEXT: fmov x12, d4 | |
| ; CHECK-GI-NEXT: mov v6.16b, v0.16b | |
| ; CHECK-GI-NEXT: mov v0.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: mov v3.d[1], v4.d[0] | |
| ; CHECK-GI-NEXT: umulh x10, x8, x9 | |
| ; CHECK-GI-NEXT: asr x11, x9, #63 | |
| ; CHECK-GI-NEXT: asr x14, x12, #63 | |
| ; CHECK-GI-NEXT: mov v6.d[1], v1.d[0] | |
| ; CHECK-GI-NEXT: fmov x15, d3 | |
| ; CHECK-GI-NEXT: madd x10, x8, x11, x10 | |
| ; CHECK-GI-NEXT: fmov x11, d1 | |
| ; CHECK-GI-NEXT: asr x8, x8, #63 | |
| ; CHECK-GI-NEXT: umulh x13, x11, x12 | |
| ; CHECK-GI-NEXT: madd x8, x8, x9, x10 | |
| ; CHECK-GI-NEXT: mov x10, v0.d[1] | |
| ; CHECK-GI-NEXT: madd x9, x11, x14, x13 | |
| ; CHECK-GI-NEXT: fmov x14, d0 | |
| ; CHECK-GI-NEXT: mov x13, v3.d[1] | |
| ; CHECK-GI-NEXT: asr x11, x11, #63 | |
| ; CHECK-GI-NEXT: mul x14, x14, x15 | |
| ; CHECK-GI-NEXT: fmov d3, x8 | |
| ; CHECK-GI-NEXT: mul x10, x10, x13 | |
| ; CHECK-GI-NEXT: adrp x13, .LCPI101_0 | |
| ; CHECK-GI-NEXT: madd x9, x11, x12, x9 | |
| ; CHECK-GI-NEXT: fmov x11, d2 | |
| ; CHECK-GI-NEXT: fmov x12, d5 | |
| ; CHECK-GI-NEXT: fmov d0, x14 | |
| ; CHECK-GI-NEXT: ldr q2, [x13, :lo12:.LCPI101_0] | |
| ; CHECK-GI-NEXT: umulh x13, x11, x12 | |
| ; CHECK-GI-NEXT: asr x14, x12, #63 | |
| ; CHECK-GI-NEXT: neg v2.2d, v2.2d | |
| ; CHECK-GI-NEXT: mov v0.d[1], x10 | |
| ; CHECK-GI-NEXT: mov v3.d[1], x9 | |
| ; CHECK-GI-NEXT: asr x9, x11, #63 | |
| ; CHECK-GI-NEXT: mul x10, x11, x12 | |
| ; CHECK-GI-NEXT: madd x8, x11, x14, x13 | |
| ; CHECK-GI-NEXT: sshl v2.2d, v0.2d, v2.2d | |
| ; CHECK-GI-NEXT: madd x8, x9, x12, x8 | |
| ; CHECK-GI-NEXT: mov w9, #191 // =0xbf | |
| ; CHECK-GI-NEXT: cmeq v2.2d, v3.2d, v2.2d | |
| ; CHECK-GI-NEXT: asr x9, x10, x9 | |
| ; CHECK-GI-NEXT: fmov d3, x9 | |
| ; CHECK-GI-NEXT: mvn v1.16b, v2.16b | |
| ; CHECK-GI-NEXT: fmov d2, x8 | |
| ; CHECK-GI-NEXT: bif v0.16b, v6.16b, v1.16b | |
| ; CHECK-GI-NEXT: cmeq v2.2d, v2.2d, v3.2d | |
| ; CHECK-GI-NEXT: mvn v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: mov d1, v0.d[1] | |
| ; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 | |
| ; CHECK-GI-NEXT: fmov x8, d2 | |
| ; CHECK-GI-NEXT: and x9, x10, x8 | |
| ; CHECK-GI-NEXT: bic x8, x11, x8 | |
| ; CHECK-GI-NEXT: orr x8, x9, x8 | |
| ; CHECK-GI-NEXT: fmov d2, x8 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i64>, <3 x i1>} @llvm.smul.with.overflow(<3 x i64> %a, <3 x i64> %b) | |
| %e0 = extractvalue {<3 x i64>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i64>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i64> %e0, <3 x i64> %a | |
| ret <3 x i64> %r | |
| } | |
| define <4 x i64> @uadd_v4i64(<4 x i64> %a, <4 x i64> %b) { | |
| ; CHECK-SD-LABEL: uadd_v4i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: add v3.2d, v1.2d, v3.2d | |
| ; CHECK-SD-NEXT: add v2.2d, v0.2d, v2.2d | |
| ; CHECK-SD-NEXT: cmhi v4.2d, v1.2d, v3.2d | |
| ; CHECK-SD-NEXT: cmhi v5.2d, v0.2d, v2.2d | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v4i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v4.2d, v0.2d, v2.2d | |
| ; CHECK-GI-NEXT: add v5.2d, v1.2d, v3.2d | |
| ; CHECK-GI-NEXT: cmhi v2.2d, v2.2d, v4.2d | |
| ; CHECK-GI-NEXT: cmhi v3.2d, v3.2d, v5.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i64>, <4 x i1>} @llvm.uadd.with.overflow(<4 x i64> %a, <4 x i64> %b) | |
| %e0 = extractvalue {<4 x i64>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i64>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i64> %e0, <4 x i64> %a | |
| ret <4 x i64> %r | |
| } | |
| define <4 x i64> @sadd_v4i64(<4 x i64> %a, <4 x i64> %b) { | |
| ; CHECK-SD-LABEL: sadd_v4i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqadd v4.2d, v1.2d, v3.2d | |
| ; CHECK-SD-NEXT: sqadd v5.2d, v0.2d, v2.2d | |
| ; CHECK-SD-NEXT: add v3.2d, v1.2d, v3.2d | |
| ; CHECK-SD-NEXT: add v2.2d, v0.2d, v2.2d | |
| ; CHECK-SD-NEXT: cmeq v4.2d, v3.2d, v4.2d | |
| ; CHECK-SD-NEXT: cmeq v5.2d, v2.2d, v5.2d | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v4i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: add v4.2d, v0.2d, v2.2d | |
| ; CHECK-GI-NEXT: add v5.2d, v1.2d, v3.2d | |
| ; CHECK-GI-NEXT: cmlt v2.2d, v2.2d, #0 | |
| ; CHECK-GI-NEXT: cmlt v3.2d, v3.2d, #0 | |
| ; CHECK-GI-NEXT: cmgt v6.2d, v0.2d, v4.2d | |
| ; CHECK-GI-NEXT: cmgt v7.2d, v1.2d, v5.2d | |
| ; CHECK-GI-NEXT: uzp1 v2.4s, v2.4s, v3.4s | |
| ; CHECK-GI-NEXT: uzp1 v3.4s, v6.4s, v7.4s | |
| ; CHECK-GI-NEXT: eor v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: sshll v3.2d, v2.2s, #0 | |
| ; CHECK-GI-NEXT: sshll2 v2.2d, v2.4s, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i64>, <4 x i1>} @llvm.sadd.with.overflow(<4 x i64> %a, <4 x i64> %b) | |
| %e0 = extractvalue {<4 x i64>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i64>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i64> %e0, <4 x i64> %a | |
| ret <4 x i64> %r | |
| } | |
| define <4 x i64> @usub_v4i64(<4 x i64> %a, <4 x i64> %b) { | |
| ; CHECK-SD-LABEL: usub_v4i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub v3.2d, v1.2d, v3.2d | |
| ; CHECK-SD-NEXT: sub v2.2d, v0.2d, v2.2d | |
| ; CHECK-SD-NEXT: cmhi v4.2d, v3.2d, v1.2d | |
| ; CHECK-SD-NEXT: cmhi v5.2d, v2.2d, v0.2d | |
| ; CHECK-SD-NEXT: bit v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v4i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v4.2d, v0.2d, v2.2d | |
| ; CHECK-GI-NEXT: sub v5.2d, v1.2d, v3.2d | |
| ; CHECK-GI-NEXT: cmhi v2.2d, v2.2d, v0.2d | |
| ; CHECK-GI-NEXT: cmhi v3.2d, v3.2d, v1.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i64>, <4 x i1>} @llvm.usub.with.overflow(<4 x i64> %a, <4 x i64> %b) | |
| %e0 = extractvalue {<4 x i64>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i64>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i64> %e0, <4 x i64> %a | |
| ret <4 x i64> %r | |
| } | |
| define <4 x i64> @ssub_v4i64(<4 x i64> %a, <4 x i64> %b) { | |
| ; CHECK-SD-LABEL: ssub_v4i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sqsub v4.2d, v1.2d, v3.2d | |
| ; CHECK-SD-NEXT: sqsub v5.2d, v0.2d, v2.2d | |
| ; CHECK-SD-NEXT: sub v3.2d, v1.2d, v3.2d | |
| ; CHECK-SD-NEXT: sub v2.2d, v0.2d, v2.2d | |
| ; CHECK-SD-NEXT: cmeq v4.2d, v3.2d, v4.2d | |
| ; CHECK-SD-NEXT: cmeq v5.2d, v2.2d, v5.2d | |
| ; CHECK-SD-NEXT: bif v0.16b, v2.16b, v5.16b | |
| ; CHECK-SD-NEXT: bif v1.16b, v3.16b, v4.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v4i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub v4.2d, v0.2d, v2.2d | |
| ; CHECK-GI-NEXT: sub v5.2d, v1.2d, v3.2d | |
| ; CHECK-GI-NEXT: cmgt v2.2d, v2.2d, v0.2d | |
| ; CHECK-GI-NEXT: cmgt v3.2d, v3.2d, v1.2d | |
| ; CHECK-GI-NEXT: cmlt v6.2d, v4.2d, #0 | |
| ; CHECK-GI-NEXT: cmlt v7.2d, v5.2d, #0 | |
| ; CHECK-GI-NEXT: uzp1 v2.4s, v2.4s, v3.4s | |
| ; CHECK-GI-NEXT: uzp1 v3.4s, v6.4s, v7.4s | |
| ; CHECK-GI-NEXT: eor v2.16b, v2.16b, v3.16b | |
| ; CHECK-GI-NEXT: sshll v3.2d, v2.2s, #0 | |
| ; CHECK-GI-NEXT: sshll2 v2.2d, v2.4s, #0 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v3.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i64>, <4 x i1>} @llvm.ssub.with.overflow(<4 x i64> %a, <4 x i64> %b) | |
| %e0 = extractvalue {<4 x i64>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i64>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i64> %e0, <4 x i64> %a | |
| ret <4 x i64> %r | |
| } | |
| define <4 x i64> @umul_v4i64(<4 x i64> %a, <4 x i64> %b) { | |
| ; CHECK-SD-LABEL: umul_v4i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: mov x8, v3.d[1] | |
| ; CHECK-SD-NEXT: mov x9, v1.d[1] | |
| ; CHECK-SD-NEXT: fmov x10, d3 | |
| ; CHECK-SD-NEXT: fmov x11, d1 | |
| ; CHECK-SD-NEXT: mov x14, v2.d[1] | |
| ; CHECK-SD-NEXT: mov x15, v0.d[1] | |
| ; CHECK-SD-NEXT: fmov x16, d0 | |
| ; CHECK-SD-NEXT: mul x12, x11, x10 | |
| ; CHECK-SD-NEXT: mul x13, x9, x8 | |
| ; CHECK-SD-NEXT: umulh x8, x9, x8 | |
| ; CHECK-SD-NEXT: umulh x9, x11, x10 | |
| ; CHECK-SD-NEXT: fmov x11, d2 | |
| ; CHECK-SD-NEXT: fmov d2, x12 | |
| ; CHECK-SD-NEXT: umulh x10, x15, x14 | |
| ; CHECK-SD-NEXT: cmp xzr, x8 | |
| ; CHECK-SD-NEXT: mov v2.d[1], x13 | |
| ; CHECK-SD-NEXT: umulh x17, x16, x11 | |
| ; CHECK-SD-NEXT: csetm x8, ne | |
| ; CHECK-SD-NEXT: cmp xzr, x9 | |
| ; CHECK-SD-NEXT: mul x11, x16, x11 | |
| ; CHECK-SD-NEXT: mul x9, x15, x14 | |
| ; CHECK-SD-NEXT: csetm x14, ne | |
| ; CHECK-SD-NEXT: cmp xzr, x10 | |
| ; CHECK-SD-NEXT: csetm x10, ne | |
| ; CHECK-SD-NEXT: cmp xzr, x17 | |
| ; CHECK-SD-NEXT: fmov d3, x14 | |
| ; CHECK-SD-NEXT: csetm x12, ne | |
| ; CHECK-SD-NEXT: fmov d4, x11 | |
| ; CHECK-SD-NEXT: fmov d5, x12 | |
| ; CHECK-SD-NEXT: mov v3.d[1], x8 | |
| ; CHECK-SD-NEXT: mov v4.d[1], x9 | |
| ; CHECK-SD-NEXT: mov v5.d[1], x10 | |
| ; CHECK-SD-NEXT: bit v1.16b, v2.16b, v3.16b | |
| ; CHECK-SD-NEXT: bit v0.16b, v4.16b, v5.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v4i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: fmov x8, d0 | |
| ; CHECK-GI-NEXT: fmov x9, d2 | |
| ; CHECK-GI-NEXT: fmov x13, d1 | |
| ; CHECK-GI-NEXT: fmov x14, d3 | |
| ; CHECK-GI-NEXT: mov x10, v2.d[1] | |
| ; CHECK-GI-NEXT: mov x11, v0.d[1] | |
| ; CHECK-GI-NEXT: mov x15, v3.d[1] | |
| ; CHECK-GI-NEXT: mov x17, v1.d[1] | |
| ; CHECK-GI-NEXT: umulh x12, x8, x9 | |
| ; CHECK-GI-NEXT: umulh x16, x13, x14 | |
| ; CHECK-GI-NEXT: umulh x18, x11, x10 | |
| ; CHECK-GI-NEXT: fmov d2, x12 | |
| ; CHECK-GI-NEXT: umulh x0, x17, x15 | |
| ; CHECK-GI-NEXT: fmov d3, x16 | |
| ; CHECK-GI-NEXT: mul x8, x8, x9 | |
| ; CHECK-GI-NEXT: mov v2.d[1], x18 | |
| ; CHECK-GI-NEXT: mul x9, x11, x10 | |
| ; CHECK-GI-NEXT: mov v3.d[1], x0 | |
| ; CHECK-GI-NEXT: mul x10, x13, x14 | |
| ; CHECK-GI-NEXT: fmov d4, x8 | |
| ; CHECK-GI-NEXT: cmtst v2.2d, v2.2d, v2.2d | |
| ; CHECK-GI-NEXT: mul x11, x17, x15 | |
| ; CHECK-GI-NEXT: cmtst v3.2d, v3.2d, v3.2d | |
| ; CHECK-GI-NEXT: mov v4.d[1], x9 | |
| ; CHECK-GI-NEXT: fmov d5, x10 | |
| ; CHECK-GI-NEXT: mov v5.d[1], x11 | |
| ; CHECK-GI-NEXT: bit v0.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v5.16b, v3.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i64>, <4 x i1>} @llvm.umul.with.overflow(<4 x i64> %a, <4 x i64> %b) | |
| %e0 = extractvalue {<4 x i64>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i64>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i64> %e0, <4 x i64> %a | |
| ret <4 x i64> %r | |
| } | |
| define <4 x i64> @smul_v4i64(<4 x i64> %a, <4 x i64> %b) { | |
| ; CHECK-SD-LABEL: smul_v4i64: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: mov x8, v3.d[1] | |
| ; CHECK-SD-NEXT: mov x9, v1.d[1] | |
| ; CHECK-SD-NEXT: fmov x10, d3 | |
| ; CHECK-SD-NEXT: fmov x11, d1 | |
| ; CHECK-SD-NEXT: mov x14, v2.d[1] | |
| ; CHECK-SD-NEXT: mov x15, v0.d[1] | |
| ; CHECK-SD-NEXT: mul x13, x9, x8 | |
| ; CHECK-SD-NEXT: smulh x8, x9, x8 | |
| ; CHECK-SD-NEXT: mul x12, x11, x10 | |
| ; CHECK-SD-NEXT: smulh x9, x11, x10 | |
| ; CHECK-SD-NEXT: cmp x8, x13, asr #63 | |
| ; CHECK-SD-NEXT: mul x10, x15, x14 | |
| ; CHECK-SD-NEXT: csetm x8, ne | |
| ; CHECK-SD-NEXT: fmov d4, x12 | |
| ; CHECK-SD-NEXT: smulh x11, x15, x14 | |
| ; CHECK-SD-NEXT: fmov x14, d2 | |
| ; CHECK-SD-NEXT: fmov x15, d0 | |
| ; CHECK-SD-NEXT: cmp x9, x12, asr #63 | |
| ; CHECK-SD-NEXT: csetm x9, ne | |
| ; CHECK-SD-NEXT: mov v4.d[1], x13 | |
| ; CHECK-SD-NEXT: mul x16, x15, x14 | |
| ; CHECK-SD-NEXT: fmov d2, x9 | |
| ; CHECK-SD-NEXT: smulh x14, x15, x14 | |
| ; CHECK-SD-NEXT: cmp x11, x10, asr #63 | |
| ; CHECK-SD-NEXT: csetm x9, ne | |
| ; CHECK-SD-NEXT: mov v2.d[1], x8 | |
| ; CHECK-SD-NEXT: fmov d5, x16 | |
| ; CHECK-SD-NEXT: cmp x14, x16, asr #63 | |
| ; CHECK-SD-NEXT: bit v1.16b, v4.16b, v2.16b | |
| ; CHECK-SD-NEXT: csetm x8, ne | |
| ; CHECK-SD-NEXT: mov v5.d[1], x10 | |
| ; CHECK-SD-NEXT: fmov d3, x8 | |
| ; CHECK-SD-NEXT: mov v3.d[1], x9 | |
| ; CHECK-SD-NEXT: bit v0.16b, v5.16b, v3.16b | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v4i64: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: mov d4, v0.d[1] | |
| ; CHECK-GI-NEXT: mov d5, v2.d[1] | |
| ; CHECK-GI-NEXT: fmov x8, d0 | |
| ; CHECK-GI-NEXT: fmov x9, d2 | |
| ; CHECK-GI-NEXT: mov x1, v1.d[1] | |
| ; CHECK-GI-NEXT: asr x15, x8, #63 | |
| ; CHECK-GI-NEXT: fmov x11, d4 | |
| ; CHECK-GI-NEXT: fmov x12, d5 | |
| ; CHECK-GI-NEXT: umulh x10, x8, x9 | |
| ; CHECK-GI-NEXT: asr x13, x9, #63 | |
| ; CHECK-GI-NEXT: mov d4, v1.d[1] | |
| ; CHECK-GI-NEXT: mov d5, v3.d[1] | |
| ; CHECK-GI-NEXT: umulh x14, x11, x12 | |
| ; CHECK-GI-NEXT: madd x10, x8, x13, x10 | |
| ; CHECK-GI-NEXT: asr x13, x12, #63 | |
| ; CHECK-GI-NEXT: fmov x16, d5 | |
| ; CHECK-GI-NEXT: madd x13, x11, x13, x14 | |
| ; CHECK-GI-NEXT: asr x11, x11, #63 | |
| ; CHECK-GI-NEXT: asr x0, x16, #63 | |
| ; CHECK-GI-NEXT: madd x10, x15, x9, x10 | |
| ; CHECK-GI-NEXT: fmov x15, d4 | |
| ; CHECK-GI-NEXT: madd x11, x11, x12, x13 | |
| ; CHECK-GI-NEXT: fmov x12, d1 | |
| ; CHECK-GI-NEXT: fmov x13, d3 | |
| ; CHECK-GI-NEXT: umulh x18, x15, x16 | |
| ; CHECK-GI-NEXT: asr x17, x13, #63 | |
| ; CHECK-GI-NEXT: fmov d5, x10 | |
| ; CHECK-GI-NEXT: umulh x14, x12, x13 | |
| ; CHECK-GI-NEXT: madd x18, x15, x0, x18 | |
| ; CHECK-GI-NEXT: mov x0, v0.d[1] | |
| ; CHECK-GI-NEXT: asr x15, x15, #63 | |
| ; CHECK-GI-NEXT: mov v5.d[1], x11 | |
| ; CHECK-GI-NEXT: madd x14, x12, x17, x14 | |
| ; CHECK-GI-NEXT: mov x17, v2.d[1] | |
| ; CHECK-GI-NEXT: movi v2.2d, #0x000000000000ff | |
| ; CHECK-GI-NEXT: mul x8, x8, x9 | |
| ; CHECK-GI-NEXT: mov x9, v3.d[1] | |
| ; CHECK-GI-NEXT: mul x17, x0, x17 | |
| ; CHECK-GI-NEXT: neg v2.2d, v2.2d | |
| ; CHECK-GI-NEXT: mul x0, x12, x13 | |
| ; CHECK-GI-NEXT: asr x12, x12, #63 | |
| ; CHECK-GI-NEXT: fmov d3, x8 | |
| ; CHECK-GI-NEXT: mul x9, x1, x9 | |
| ; CHECK-GI-NEXT: madd x12, x12, x13, x14 | |
| ; CHECK-GI-NEXT: mov v3.d[1], x17 | |
| ; CHECK-GI-NEXT: fmov d4, x0 | |
| ; CHECK-GI-NEXT: madd x13, x15, x16, x18 | |
| ; CHECK-GI-NEXT: mov v4.d[1], x9 | |
| ; CHECK-GI-NEXT: sshl v7.2d, v3.2d, v2.2d | |
| ; CHECK-GI-NEXT: fmov d6, x12 | |
| ; CHECK-GI-NEXT: cmeq v5.2d, v5.2d, v7.2d | |
| ; CHECK-GI-NEXT: mov v6.d[1], x13 | |
| ; CHECK-GI-NEXT: sshl v2.2d, v4.2d, v2.2d | |
| ; CHECK-GI-NEXT: mvn v5.16b, v5.16b | |
| ; CHECK-GI-NEXT: cmeq v2.2d, v6.2d, v2.2d | |
| ; CHECK-GI-NEXT: bit v0.16b, v3.16b, v5.16b | |
| ; CHECK-GI-NEXT: mvn v2.16b, v2.16b | |
| ; CHECK-GI-NEXT: bit v1.16b, v4.16b, v2.16b | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i64>, <4 x i1>} @llvm.smul.with.overflow(<4 x i64> %a, <4 x i64> %b) | |
| %e0 = extractvalue {<4 x i64>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i64>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i64> %e0, <4 x i64> %a | |
| ret <4 x i64> %r | |
| } | |
| define <2 x i128> @uadd_v2i128(<2 x i128> %a, <2 x i128> %b) { | |
| ; CHECK-SD-LABEL: uadd_v2i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: adds x8, x0, x4 | |
| ; CHECK-SD-NEXT: adcs x9, x1, x5 | |
| ; CHECK-SD-NEXT: csel x1, x9, x1, hs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, hs | |
| ; CHECK-SD-NEXT: adds x8, x2, x6 | |
| ; CHECK-SD-NEXT: adcs x9, x3, x7 | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, hs | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, hs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v2i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: adds x8, x0, x4 | |
| ; CHECK-GI-NEXT: adc x9, x1, x5 | |
| ; CHECK-GI-NEXT: adds x10, x2, x6 | |
| ; CHECK-GI-NEXT: adc x11, x3, x7 | |
| ; CHECK-GI-NEXT: cmp x8, x4 | |
| ; CHECK-GI-NEXT: cset w12, lo | |
| ; CHECK-GI-NEXT: cmp x9, x5 | |
| ; CHECK-GI-NEXT: cset w13, lo | |
| ; CHECK-GI-NEXT: csel w12, w12, w13, eq | |
| ; CHECK-GI-NEXT: cmp x10, x6 | |
| ; CHECK-GI-NEXT: cset w13, lo | |
| ; CHECK-GI-NEXT: cmp x11, x7 | |
| ; CHECK-GI-NEXT: cset w14, lo | |
| ; CHECK-GI-NEXT: csel w13, w13, w14, eq | |
| ; CHECK-GI-NEXT: tst w12, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x8, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x9, x1, ne | |
| ; CHECK-GI-NEXT: tst w13, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x11, x3, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i128>, <2 x i1>} @llvm.uadd.with.overflow(<2 x i128> %a, <2 x i128> %b) | |
| %e0 = extractvalue {<2 x i128>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i128>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i128> %e0, <2 x i128> %a | |
| ret <2 x i128> %r | |
| } | |
| define <2 x i128> @sadd_v2i128(<2 x i128> %a, <2 x i128> %b) { | |
| ; CHECK-SD-LABEL: sadd_v2i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: adds x8, x0, x4 | |
| ; CHECK-SD-NEXT: adcs x9, x1, x5 | |
| ; CHECK-SD-NEXT: csel x1, x9, x1, vs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, vs | |
| ; CHECK-SD-NEXT: adds x8, x2, x6 | |
| ; CHECK-SD-NEXT: adcs x9, x3, x7 | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, vs | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, vs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v2i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: adds x8, x0, x4 | |
| ; CHECK-GI-NEXT: adc x9, x1, x5 | |
| ; CHECK-GI-NEXT: adds x10, x2, x6 | |
| ; CHECK-GI-NEXT: adc x11, x3, x7 | |
| ; CHECK-GI-NEXT: cmp x8, x0 | |
| ; CHECK-GI-NEXT: cset w12, lo | |
| ; CHECK-GI-NEXT: cmp x9, x1 | |
| ; CHECK-GI-NEXT: cset w13, lt | |
| ; CHECK-GI-NEXT: csel w12, w12, w13, eq | |
| ; CHECK-GI-NEXT: cmp x10, x2 | |
| ; CHECK-GI-NEXT: cset w13, lo | |
| ; CHECK-GI-NEXT: cmp x11, x3 | |
| ; CHECK-GI-NEXT: fmov s1, w12 | |
| ; CHECK-GI-NEXT: cset w14, lt | |
| ; CHECK-GI-NEXT: csel w13, w13, w14, eq | |
| ; CHECK-GI-NEXT: cmp x5, #0 | |
| ; CHECK-GI-NEXT: cset w14, mi | |
| ; CHECK-GI-NEXT: mov v1.s[1], w13 | |
| ; CHECK-GI-NEXT: csel w14, wzr, w14, eq | |
| ; CHECK-GI-NEXT: cmp x7, #0 | |
| ; CHECK-GI-NEXT: fmov s0, w14 | |
| ; CHECK-GI-NEXT: cset w15, mi | |
| ; CHECK-GI-NEXT: csel w15, wzr, w15, eq | |
| ; CHECK-GI-NEXT: mov v0.s[1], w15 | |
| ; CHECK-GI-NEXT: eor v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: mov s1, v0.s[1] | |
| ; CHECK-GI-NEXT: fmov w12, s0 | |
| ; CHECK-GI-NEXT: tst w12, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x8, x0, ne | |
| ; CHECK-GI-NEXT: fmov w8, s1 | |
| ; CHECK-GI-NEXT: tst w12, #0x1 | |
| ; CHECK-GI-NEXT: csel x1, x9, x1, ne | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x3, x11, x3, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i128>, <2 x i1>} @llvm.sadd.with.overflow(<2 x i128> %a, <2 x i128> %b) | |
| %e0 = extractvalue {<2 x i128>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i128>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i128> %e0, <2 x i128> %a | |
| ret <2 x i128> %r | |
| } | |
| define <2 x i128> @usub_v2i128(<2 x i128> %a, <2 x i128> %b) { | |
| ; CHECK-SD-LABEL: usub_v2i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: subs x8, x0, x4 | |
| ; CHECK-SD-NEXT: sbcs x9, x1, x5 | |
| ; CHECK-SD-NEXT: csel x1, x9, x1, lo | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, lo | |
| ; CHECK-SD-NEXT: subs x8, x2, x6 | |
| ; CHECK-SD-NEXT: sbcs x9, x3, x7 | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, lo | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, lo | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v2i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: subs x8, x0, x4 | |
| ; CHECK-GI-NEXT: sbc x9, x1, x5 | |
| ; CHECK-GI-NEXT: subs x10, x2, x6 | |
| ; CHECK-GI-NEXT: sbc x11, x3, x7 | |
| ; CHECK-GI-NEXT: cmp x0, x4 | |
| ; CHECK-GI-NEXT: cset w12, lo | |
| ; CHECK-GI-NEXT: cmp x1, x5 | |
| ; CHECK-GI-NEXT: cset w13, lo | |
| ; CHECK-GI-NEXT: csel w12, w12, w13, eq | |
| ; CHECK-GI-NEXT: cmp x2, x6 | |
| ; CHECK-GI-NEXT: cset w13, lo | |
| ; CHECK-GI-NEXT: cmp x3, x7 | |
| ; CHECK-GI-NEXT: cset w14, lo | |
| ; CHECK-GI-NEXT: csel w13, w13, w14, eq | |
| ; CHECK-GI-NEXT: tst w12, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x8, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x9, x1, ne | |
| ; CHECK-GI-NEXT: tst w13, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x11, x3, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i128>, <2 x i1>} @llvm.usub.with.overflow(<2 x i128> %a, <2 x i128> %b) | |
| %e0 = extractvalue {<2 x i128>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i128>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i128> %e0, <2 x i128> %a | |
| ret <2 x i128> %r | |
| } | |
| define <2 x i128> @ssub_v2i128(<2 x i128> %a, <2 x i128> %b) { | |
| ; CHECK-SD-LABEL: ssub_v2i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: subs x8, x0, x4 | |
| ; CHECK-SD-NEXT: sbcs x9, x1, x5 | |
| ; CHECK-SD-NEXT: csel x1, x9, x1, vs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, vs | |
| ; CHECK-SD-NEXT: subs x8, x2, x6 | |
| ; CHECK-SD-NEXT: sbcs x9, x3, x7 | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, vs | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, vs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v2i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: subs x8, x0, x4 | |
| ; CHECK-GI-NEXT: sbc x9, x1, x5 | |
| ; CHECK-GI-NEXT: subs x10, x2, x6 | |
| ; CHECK-GI-NEXT: sbc x11, x3, x7 | |
| ; CHECK-GI-NEXT: cmp x0, x4 | |
| ; CHECK-GI-NEXT: cset w12, lo | |
| ; CHECK-GI-NEXT: cmp x1, x5 | |
| ; CHECK-GI-NEXT: cset w13, lt | |
| ; CHECK-GI-NEXT: csel w12, w12, w13, eq | |
| ; CHECK-GI-NEXT: cmp x2, x6 | |
| ; CHECK-GI-NEXT: cset w13, lo | |
| ; CHECK-GI-NEXT: cmp x3, x7 | |
| ; CHECK-GI-NEXT: fmov s0, w12 | |
| ; CHECK-GI-NEXT: cset w14, lt | |
| ; CHECK-GI-NEXT: csel w13, w13, w14, eq | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: cset w14, mi | |
| ; CHECK-GI-NEXT: mov v0.s[1], w13 | |
| ; CHECK-GI-NEXT: csel w14, wzr, w14, eq | |
| ; CHECK-GI-NEXT: cmp x11, #0 | |
| ; CHECK-GI-NEXT: fmov s1, w14 | |
| ; CHECK-GI-NEXT: cset w15, mi | |
| ; CHECK-GI-NEXT: csel w15, wzr, w15, eq | |
| ; CHECK-GI-NEXT: mov v1.s[1], w15 | |
| ; CHECK-GI-NEXT: eor v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: mov s1, v0.s[1] | |
| ; CHECK-GI-NEXT: fmov w12, s0 | |
| ; CHECK-GI-NEXT: tst w12, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x8, x0, ne | |
| ; CHECK-GI-NEXT: fmov w8, s1 | |
| ; CHECK-GI-NEXT: tst w12, #0x1 | |
| ; CHECK-GI-NEXT: csel x1, x9, x1, ne | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x3, x11, x3, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i128>, <2 x i1>} @llvm.ssub.with.overflow(<2 x i128> %a, <2 x i128> %b) | |
| %e0 = extractvalue {<2 x i128>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i128>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i128> %e0, <2 x i128> %a | |
| ret <2 x i128> %r | |
| } | |
| define <2 x i128> @umul_v2i128(<2 x i128> %a, <2 x i128> %b) { | |
| ; CHECK-SD-LABEL: umul_v2i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: mul x9, x7, x2 | |
| ; CHECK-SD-NEXT: cmp x3, #0 | |
| ; CHECK-SD-NEXT: ccmp x7, #0, #4, ne | |
| ; CHECK-SD-NEXT: umulh x10, x3, x6 | |
| ; CHECK-SD-NEXT: umulh x8, x7, x2 | |
| ; CHECK-SD-NEXT: madd x9, x3, x6, x9 | |
| ; CHECK-SD-NEXT: ccmp xzr, x10, #0, eq | |
| ; CHECK-SD-NEXT: umulh x11, x2, x6 | |
| ; CHECK-SD-NEXT: ccmp xzr, x8, #0, eq | |
| ; CHECK-SD-NEXT: mul x13, x5, x0 | |
| ; CHECK-SD-NEXT: cset w8, ne | |
| ; CHECK-SD-NEXT: umulh x14, x1, x4 | |
| ; CHECK-SD-NEXT: adds x9, x11, x9 | |
| ; CHECK-SD-NEXT: umulh x12, x5, x0 | |
| ; CHECK-SD-NEXT: csinc w8, w8, wzr, lo | |
| ; CHECK-SD-NEXT: cmp x1, #0 | |
| ; CHECK-SD-NEXT: ccmp x5, #0, #4, ne | |
| ; CHECK-SD-NEXT: madd x10, x1, x4, x13 | |
| ; CHECK-SD-NEXT: ccmp xzr, x14, #0, eq | |
| ; CHECK-SD-NEXT: umulh x11, x0, x4 | |
| ; CHECK-SD-NEXT: ccmp xzr, x12, #0, eq | |
| ; CHECK-SD-NEXT: mul x13, x0, x4 | |
| ; CHECK-SD-NEXT: cset w14, ne | |
| ; CHECK-SD-NEXT: mul x12, x2, x6 | |
| ; CHECK-SD-NEXT: adds x10, x11, x10 | |
| ; CHECK-SD-NEXT: csinc w11, w14, wzr, lo | |
| ; CHECK-SD-NEXT: cmp w11, #0 | |
| ; CHECK-SD-NEXT: csel x0, x13, x0, ne | |
| ; CHECK-SD-NEXT: csel x1, x10, x1, ne | |
| ; CHECK-SD-NEXT: cmp w8, #0 | |
| ; CHECK-SD-NEXT: csel x2, x12, x2, ne | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, ne | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v2i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #-32]! // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: umulh x10, x0, x4 | |
| ; CHECK-GI-NEXT: mul x16, x0, x5 | |
| ; CHECK-GI-NEXT: mul x11, x1, x4 | |
| ; CHECK-GI-NEXT: umulh x13, x1, x4 | |
| ; CHECK-GI-NEXT: adds x16, x10, x16 | |
| ; CHECK-GI-NEXT: umulh x15, x0, x5 | |
| ; CHECK-GI-NEXT: mul x14, x1, x5 | |
| ; CHECK-GI-NEXT: umulh x12, x1, x5 | |
| ; CHECK-GI-NEXT: umulh x17, x2, x6 | |
| ; CHECK-GI-NEXT: mul x18, x2, x7 | |
| ; CHECK-GI-NEXT: madd x10, x0, x5, x10 | |
| ; CHECK-GI-NEXT: cset w5, hs | |
| ; CHECK-GI-NEXT: cmn x16, x11 | |
| ; CHECK-GI-NEXT: cset w11, hs | |
| ; CHECK-GI-NEXT: adds x13, x13, x15 | |
| ; CHECK-GI-NEXT: and x5, x5, #0x1 | |
| ; CHECK-GI-NEXT: mul x19, x3, x6 | |
| ; CHECK-GI-NEXT: and x11, x11, #0x1 | |
| ; CHECK-GI-NEXT: cset w15, hs | |
| ; CHECK-GI-NEXT: adds x13, x13, x14 | |
| ; CHECK-GI-NEXT: add x11, x5, x11 | |
| ; CHECK-GI-NEXT: and x15, x15, #0x1 | |
| ; CHECK-GI-NEXT: umulh x20, x3, x6 | |
| ; CHECK-GI-NEXT: cset w5, hs | |
| ; CHECK-GI-NEXT: adds x11, x13, x11 | |
| ; CHECK-GI-NEXT: and x5, x5, #0x1 | |
| ; CHECK-GI-NEXT: umulh x21, x2, x7 | |
| ; CHECK-GI-NEXT: add x15, x15, x5 | |
| ; CHECK-GI-NEXT: cset w5, hs | |
| ; CHECK-GI-NEXT: adds x18, x17, x18 | |
| ; CHECK-GI-NEXT: and x5, x5, #0x1 | |
| ; CHECK-GI-NEXT: umulh x9, x4, xzr | |
| ; CHECK-GI-NEXT: add x15, x15, x5 | |
| ; CHECK-GI-NEXT: mul x22, x3, x7 | |
| ; CHECK-GI-NEXT: umulh x8, x0, xzr | |
| ; CHECK-GI-NEXT: add x9, x9, x12 | |
| ; CHECK-GI-NEXT: umulh x14, x3, x7 | |
| ; CHECK-GI-NEXT: madd x17, x2, x7, x17 | |
| ; CHECK-GI-NEXT: cset w7, hs | |
| ; CHECK-GI-NEXT: cmn x18, x19 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: adds x5, x20, x21 | |
| ; CHECK-GI-NEXT: and x7, x7, #0x1 | |
| ; CHECK-GI-NEXT: umulh x16, x6, xzr | |
| ; CHECK-GI-NEXT: cset w12, hs | |
| ; CHECK-GI-NEXT: adds x5, x5, x22 | |
| ; CHECK-GI-NEXT: and x18, x18, #0x1 | |
| ; CHECK-GI-NEXT: and x12, x12, #0x1 | |
| ; CHECK-GI-NEXT: add x8, x9, x8 | |
| ; CHECK-GI-NEXT: umulh x13, x2, xzr | |
| ; CHECK-GI-NEXT: add x18, x7, x18 | |
| ; CHECK-GI-NEXT: cset w7, hs | |
| ; CHECK-GI-NEXT: and x7, x7, #0x1 | |
| ; CHECK-GI-NEXT: adds x18, x5, x18 | |
| ; CHECK-GI-NEXT: add x8, x8, x15 | |
| ; CHECK-GI-NEXT: madd x10, x1, x4, x10 | |
| ; CHECK-GI-NEXT: add x9, x12, x7 | |
| ; CHECK-GI-NEXT: cset w12, hs | |
| ; CHECK-GI-NEXT: add x14, x16, x14 | |
| ; CHECK-GI-NEXT: and x12, x12, #0x1 | |
| ; CHECK-GI-NEXT: orr x8, x11, x8 | |
| ; CHECK-GI-NEXT: mul x4, x0, x4 | |
| ; CHECK-GI-NEXT: add x9, x9, x12 | |
| ; CHECK-GI-NEXT: cmp x8, #0 | |
| ; CHECK-GI-NEXT: add x12, x14, x13 | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: mul x5, x2, x6 | |
| ; CHECK-GI-NEXT: add x9, x12, x9 | |
| ; CHECK-GI-NEXT: orr x9, x18, x9 | |
| ; CHECK-GI-NEXT: csel x1, x10, x1, ne | |
| ; CHECK-GI-NEXT: madd x16, x3, x6, x17 | |
| ; CHECK-GI-NEXT: csel x0, x4, x0, ne | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: csel x2, x5, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x16, x3, ne | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp], #32 // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i128>, <2 x i1>} @llvm.umul.with.overflow(<2 x i128> %a, <2 x i128> %b) | |
| %e0 = extractvalue {<2 x i128>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i128>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i128> %e0, <2 x i128> %a | |
| ret <2 x i128> %r | |
| } | |
| define <2 x i128> @smul_v2i128(<2 x i128> %a, <2 x i128> %b) { | |
| ; CHECK-SD-LABEL: smul_v2i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: stp x20, x19, [sp, #-16]! // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: .cfi_def_cfa_offset 16 | |
| ; CHECK-SD-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-SD-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-SD-NEXT: asr x9, x3, #63 | |
| ; CHECK-SD-NEXT: umulh x10, x2, x6 | |
| ; CHECK-SD-NEXT: asr x13, x7, #63 | |
| ; CHECK-SD-NEXT: asr x18, x1, #63 | |
| ; CHECK-SD-NEXT: mul x11, x3, x6 | |
| ; CHECK-SD-NEXT: umulh x8, x3, x6 | |
| ; CHECK-SD-NEXT: mul x9, x9, x6 | |
| ; CHECK-SD-NEXT: adds x10, x11, x10 | |
| ; CHECK-SD-NEXT: mul x14, x2, x7 | |
| ; CHECK-SD-NEXT: umulh x12, x2, x7 | |
| ; CHECK-SD-NEXT: adc x8, x8, x9 | |
| ; CHECK-SD-NEXT: mul x13, x2, x13 | |
| ; CHECK-SD-NEXT: adds x9, x14, x10 | |
| ; CHECK-SD-NEXT: asr x10, x5, #63 | |
| ; CHECK-SD-NEXT: mul x16, x3, x7 | |
| ; CHECK-SD-NEXT: smulh x15, x3, x7 | |
| ; CHECK-SD-NEXT: adc x12, x12, x13 | |
| ; CHECK-SD-NEXT: asr x13, x8, #63 | |
| ; CHECK-SD-NEXT: umulh x7, x0, x4 | |
| ; CHECK-SD-NEXT: asr x20, x12, #63 | |
| ; CHECK-SD-NEXT: adds x8, x8, x12 | |
| ; CHECK-SD-NEXT: mul x19, x1, x4 | |
| ; CHECK-SD-NEXT: adc x12, x13, x20 | |
| ; CHECK-SD-NEXT: adds x8, x16, x8 | |
| ; CHECK-SD-NEXT: adc x12, x15, x12 | |
| ; CHECK-SD-NEXT: umulh x17, x1, x4 | |
| ; CHECK-SD-NEXT: mul x18, x18, x4 | |
| ; CHECK-SD-NEXT: adds x15, x19, x7 | |
| ; CHECK-SD-NEXT: mul x14, x0, x5 | |
| ; CHECK-SD-NEXT: umulh x11, x0, x5 | |
| ; CHECK-SD-NEXT: adc x16, x17, x18 | |
| ; CHECK-SD-NEXT: mul x10, x0, x10 | |
| ; CHECK-SD-NEXT: adds x14, x14, x15 | |
| ; CHECK-SD-NEXT: mul x13, x1, x5 | |
| ; CHECK-SD-NEXT: smulh x15, x1, x5 | |
| ; CHECK-SD-NEXT: adc x10, x11, x10 | |
| ; CHECK-SD-NEXT: asr x11, x16, #63 | |
| ; CHECK-SD-NEXT: asr x17, x10, #63 | |
| ; CHECK-SD-NEXT: adds x10, x16, x10 | |
| ; CHECK-SD-NEXT: mul x16, x0, x4 | |
| ; CHECK-SD-NEXT: adc x11, x11, x17 | |
| ; CHECK-SD-NEXT: adds x10, x13, x10 | |
| ; CHECK-SD-NEXT: asr x13, x14, #63 | |
| ; CHECK-SD-NEXT: asr x17, x9, #63 | |
| ; CHECK-SD-NEXT: adc x11, x15, x11 | |
| ; CHECK-SD-NEXT: mul x15, x2, x6 | |
| ; CHECK-SD-NEXT: eor x11, x11, x13 | |
| ; CHECK-SD-NEXT: eor x10, x10, x13 | |
| ; CHECK-SD-NEXT: eor x12, x12, x17 | |
| ; CHECK-SD-NEXT: eor x8, x8, x17 | |
| ; CHECK-SD-NEXT: orr x10, x10, x11 | |
| ; CHECK-SD-NEXT: orr x8, x8, x12 | |
| ; CHECK-SD-NEXT: cmp x10, #0 | |
| ; CHECK-SD-NEXT: csel x0, x16, x0, ne | |
| ; CHECK-SD-NEXT: csel x1, x14, x1, ne | |
| ; CHECK-SD-NEXT: cmp x8, #0 | |
| ; CHECK-SD-NEXT: csel x2, x15, x2, ne | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, ne | |
| ; CHECK-SD-NEXT: ldp x20, x19, [sp], #16 // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v2i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: stp x26, x25, [sp, #-64]! // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x24, x23, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #48] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 64 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-GI-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-GI-NEXT: .cfi_offset w25, -56 | |
| ; CHECK-GI-NEXT: .cfi_offset w26, -64 | |
| ; CHECK-GI-NEXT: asr x9, x1, #63 | |
| ; CHECK-GI-NEXT: asr x13, x5, #63 | |
| ; CHECK-GI-NEXT: umulh x14, x1, x5 | |
| ; CHECK-GI-NEXT: asr x22, x7, #63 | |
| ; CHECK-GI-NEXT: umulh x12, x9, x4 | |
| ; CHECK-GI-NEXT: umulh x15, x0, x13 | |
| ; CHECK-GI-NEXT: mul x20, x0, x13 | |
| ; CHECK-GI-NEXT: add x12, x12, x14 | |
| ; CHECK-GI-NEXT: umulh x23, x3, x7 | |
| ; CHECK-GI-NEXT: add x12, x12, x15 | |
| ; CHECK-GI-NEXT: madd x12, x0, x13, x12 | |
| ; CHECK-GI-NEXT: umulh x24, x2, x22 | |
| ; CHECK-GI-NEXT: madd x12, x1, x13, x12 | |
| ; CHECK-GI-NEXT: asr x13, x3, #63 | |
| ; CHECK-GI-NEXT: umulh x21, x13, x6 | |
| ; CHECK-GI-NEXT: umulh x8, x0, x4 | |
| ; CHECK-GI-NEXT: mul x10, x0, x5 | |
| ; CHECK-GI-NEXT: add x21, x21, x23 | |
| ; CHECK-GI-NEXT: mul x11, x1, x4 | |
| ; CHECK-GI-NEXT: add x21, x21, x24 | |
| ; CHECK-GI-NEXT: umulh x18, x1, x4 | |
| ; CHECK-GI-NEXT: adds x10, x8, x10 | |
| ; CHECK-GI-NEXT: umulh x19, x0, x5 | |
| ; CHECK-GI-NEXT: cset w23, hs | |
| ; CHECK-GI-NEXT: cmn x10, x11 | |
| ; CHECK-GI-NEXT: mul x16, x1, x5 | |
| ; CHECK-GI-NEXT: cset w11, hs | |
| ; CHECK-GI-NEXT: and x11, x11, #0x1 | |
| ; CHECK-GI-NEXT: madd x12, x9, x5, x12 | |
| ; CHECK-GI-NEXT: adds x18, x18, x19 | |
| ; CHECK-GI-NEXT: mul x17, x9, x4 | |
| ; CHECK-GI-NEXT: cset w19, hs | |
| ; CHECK-GI-NEXT: adds x18, x18, x20 | |
| ; CHECK-GI-NEXT: and x19, x19, #0x1 | |
| ; CHECK-GI-NEXT: madd x21, x2, x22, x21 | |
| ; CHECK-GI-NEXT: madd x9, x9, x4, x12 | |
| ; CHECK-GI-NEXT: umulh x12, x2, x6 | |
| ; CHECK-GI-NEXT: mul x15, x2, x7 | |
| ; CHECK-GI-NEXT: mul x14, x3, x6 | |
| ; CHECK-GI-NEXT: madd x20, x3, x22, x21 | |
| ; CHECK-GI-NEXT: and x21, x23, #0x1 | |
| ; CHECK-GI-NEXT: add x11, x21, x11 | |
| ; CHECK-GI-NEXT: umulh x25, x3, x6 | |
| ; CHECK-GI-NEXT: umulh x26, x2, x7 | |
| ; CHECK-GI-NEXT: mul x10, x2, x22 | |
| ; CHECK-GI-NEXT: cset w22, hs | |
| ; CHECK-GI-NEXT: adds x16, x18, x16 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: adds x16, x16, x17 | |
| ; CHECK-GI-NEXT: and x22, x22, #0x1 | |
| ; CHECK-GI-NEXT: madd x17, x13, x7, x20 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: adds x11, x16, x11 | |
| ; CHECK-GI-NEXT: cset w16, hs | |
| ; CHECK-GI-NEXT: adds x15, x12, x15 | |
| ; CHECK-GI-NEXT: add x19, x19, x22 | |
| ; CHECK-GI-NEXT: mul x23, x3, x7 | |
| ; CHECK-GI-NEXT: and x18, x18, #0x1 | |
| ; CHECK-GI-NEXT: cset w22, hs | |
| ; CHECK-GI-NEXT: cmn x15, x14 | |
| ; CHECK-GI-NEXT: add x14, x19, x18 | |
| ; CHECK-GI-NEXT: and x16, x16, #0x1 | |
| ; CHECK-GI-NEXT: mul x21, x13, x6 | |
| ; CHECK-GI-NEXT: cset w15, hs | |
| ; CHECK-GI-NEXT: adds x18, x25, x26 | |
| ; CHECK-GI-NEXT: and x15, x15, #0x1 | |
| ; CHECK-GI-NEXT: madd x13, x13, x6, x17 | |
| ; CHECK-GI-NEXT: cset w17, hs | |
| ; CHECK-GI-NEXT: adds x10, x18, x10 | |
| ; CHECK-GI-NEXT: and x18, x20, #0x1 | |
| ; CHECK-GI-NEXT: and x17, x17, #0x1 | |
| ; CHECK-GI-NEXT: add x14, x14, x18 | |
| ; CHECK-GI-NEXT: madd x8, x0, x5, x8 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: adds x10, x10, x23 | |
| ; CHECK-GI-NEXT: and x18, x18, #0x1 | |
| ; CHECK-GI-NEXT: and x5, x22, #0x1 | |
| ; CHECK-GI-NEXT: madd x12, x2, x7, x12 | |
| ; CHECK-GI-NEXT: add x17, x17, x18 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: add x15, x5, x15 | |
| ; CHECK-GI-NEXT: and x18, x18, #0x1 | |
| ; CHECK-GI-NEXT: adds x10, x10, x21 | |
| ; CHECK-GI-NEXT: madd x8, x1, x4, x8 | |
| ; CHECK-GI-NEXT: add x17, x17, x18 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: adds x10, x10, x15 | |
| ; CHECK-GI-NEXT: and x15, x18, #0x1 | |
| ; CHECK-GI-NEXT: add x14, x14, x16 | |
| ; CHECK-GI-NEXT: madd x12, x3, x6, x12 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: add x15, x17, x15 | |
| ; CHECK-GI-NEXT: and x17, x18, #0x1 | |
| ; CHECK-GI-NEXT: add x9, x9, x14 | |
| ; CHECK-GI-NEXT: add x15, x15, x17 | |
| ; CHECK-GI-NEXT: mul x16, x0, x4 | |
| ; CHECK-GI-NEXT: add x13, x13, x15 | |
| ; CHECK-GI-NEXT: eor x11, x11, x8, asr #63 | |
| ; CHECK-GI-NEXT: eor x9, x9, x8, asr #63 | |
| ; CHECK-GI-NEXT: mul x14, x2, x6 | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #48] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: eor x10, x10, x12, asr #63 | |
| ; CHECK-GI-NEXT: eor x13, x13, x12, asr #63 | |
| ; CHECK-GI-NEXT: orr x9, x11, x9 | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: orr x10, x10, x13 | |
| ; CHECK-GI-NEXT: ldp x24, x23, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x0, x16, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x8, x1, ne | |
| ; CHECK-GI-NEXT: cmp x10, #0 | |
| ; CHECK-GI-NEXT: csel x2, x14, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x12, x3, ne | |
| ; CHECK-GI-NEXT: ldp x26, x25, [sp], #64 // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<2 x i128>, <2 x i1>} @llvm.smul.with.overflow(<2 x i128> %a, <2 x i128> %b) | |
| %e0 = extractvalue {<2 x i128>, <2 x i1>} %o, 0 | |
| %e1 = extractvalue {<2 x i128>, <2 x i1>} %o, 1 | |
| %r = select <2 x i1> %e1, <2 x i128> %e0, <2 x i128> %a | |
| ret <2 x i128> %r | |
| } | |
| define <3 x i128> @uadd_v3i128(<3 x i128> %a, <3 x i128> %b) { | |
| ; CHECK-SD-LABEL: uadd_v3i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp] | |
| ; CHECK-SD-NEXT: adds x8, x2, x8 | |
| ; CHECK-SD-NEXT: adcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, hs | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #16] | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, hs | |
| ; CHECK-SD-NEXT: adds x8, x0, x6 | |
| ; CHECK-SD-NEXT: adcs x11, x1, x7 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, hs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, hs | |
| ; CHECK-SD-NEXT: adds x8, x4, x9 | |
| ; CHECK-SD-NEXT: adcs x9, x5, x10 | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, hs | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, hs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v3i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: ldp x8, x9, [sp] | |
| ; CHECK-GI-NEXT: adds x10, x0, x6 | |
| ; CHECK-GI-NEXT: ldp x11, x12, [sp, #16] | |
| ; CHECK-GI-NEXT: adc x13, x1, x7 | |
| ; CHECK-GI-NEXT: adds x14, x2, x8 | |
| ; CHECK-GI-NEXT: adc x15, x3, x9 | |
| ; CHECK-GI-NEXT: adds x16, x4, x11 | |
| ; CHECK-GI-NEXT: adc x17, x5, x12 | |
| ; CHECK-GI-NEXT: cmp x10, x6 | |
| ; CHECK-GI-NEXT: cset w18, lo | |
| ; CHECK-GI-NEXT: cmp x13, x7 | |
| ; CHECK-GI-NEXT: cset w6, lo | |
| ; CHECK-GI-NEXT: csel w18, w18, w6, eq | |
| ; CHECK-GI-NEXT: cmp x14, x8 | |
| ; CHECK-GI-NEXT: cset w8, lo | |
| ; CHECK-GI-NEXT: cmp x15, x9 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: csel w8, w8, w9, eq | |
| ; CHECK-GI-NEXT: cmp x16, x11 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: cmp x17, x12 | |
| ; CHECK-GI-NEXT: cset w11, lo | |
| ; CHECK-GI-NEXT: csel w9, w9, w11, eq | |
| ; CHECK-GI-NEXT: tst w18, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x10, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x13, x1, ne | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x14, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x15, x3, ne | |
| ; CHECK-GI-NEXT: tst w9, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x16, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x17, x5, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i128>, <3 x i1>} @llvm.uadd.with.overflow(<3 x i128> %a, <3 x i128> %b) | |
| %e0 = extractvalue {<3 x i128>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i128>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i128> %e0, <3 x i128> %a | |
| ret <3 x i128> %r | |
| } | |
| define <3 x i128> @sadd_v3i128(<3 x i128> %a, <3 x i128> %b) { | |
| ; CHECK-SD-LABEL: sadd_v3i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp] | |
| ; CHECK-SD-NEXT: adds x8, x2, x8 | |
| ; CHECK-SD-NEXT: adcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, vs | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #16] | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, vs | |
| ; CHECK-SD-NEXT: adds x8, x0, x6 | |
| ; CHECK-SD-NEXT: adcs x11, x1, x7 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, vs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, vs | |
| ; CHECK-SD-NEXT: adds x8, x4, x9 | |
| ; CHECK-SD-NEXT: adcs x9, x5, x10 | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, vs | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, vs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v3i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: ldp x8, x14, [sp] | |
| ; CHECK-GI-NEXT: adds x10, x0, x6 | |
| ; CHECK-GI-NEXT: ldp x9, x15, [sp, #16] | |
| ; CHECK-GI-NEXT: adc x13, x1, x7 | |
| ; CHECK-GI-NEXT: adds x11, x2, x8 | |
| ; CHECK-GI-NEXT: adc x12, x3, x14 | |
| ; CHECK-GI-NEXT: adds x8, x4, x9 | |
| ; CHECK-GI-NEXT: adc x9, x5, x15 | |
| ; CHECK-GI-NEXT: cmp x10, x0 | |
| ; CHECK-GI-NEXT: cset w16, lo | |
| ; CHECK-GI-NEXT: cmp x13, x1 | |
| ; CHECK-GI-NEXT: cset w17, lt | |
| ; CHECK-GI-NEXT: csel w16, w16, w17, eq | |
| ; CHECK-GI-NEXT: cmp x11, x2 | |
| ; CHECK-GI-NEXT: cset w17, lo | |
| ; CHECK-GI-NEXT: cmp x12, x3 | |
| ; CHECK-GI-NEXT: fmov s0, w16 | |
| ; CHECK-GI-NEXT: cset w18, lt | |
| ; CHECK-GI-NEXT: csel w17, w17, w18, eq | |
| ; CHECK-GI-NEXT: cmp x8, x4 | |
| ; CHECK-GI-NEXT: cset w18, lo | |
| ; CHECK-GI-NEXT: cmp x9, x5 | |
| ; CHECK-GI-NEXT: mov v0.h[1], w17 | |
| ; CHECK-GI-NEXT: cset w6, lt | |
| ; CHECK-GI-NEXT: csel w18, w18, w6, eq | |
| ; CHECK-GI-NEXT: cmp x7, #0 | |
| ; CHECK-GI-NEXT: cset w6, mi | |
| ; CHECK-GI-NEXT: csel w6, wzr, w6, eq | |
| ; CHECK-GI-NEXT: cmp x14, #0 | |
| ; CHECK-GI-NEXT: mov v0.h[2], w18 | |
| ; CHECK-GI-NEXT: fmov s1, w6 | |
| ; CHECK-GI-NEXT: cset w14, mi | |
| ; CHECK-GI-NEXT: csel w14, wzr, w14, eq | |
| ; CHECK-GI-NEXT: cmp x15, #0 | |
| ; CHECK-GI-NEXT: mov v1.h[1], w14 | |
| ; CHECK-GI-NEXT: cset w14, mi | |
| ; CHECK-GI-NEXT: csel w14, wzr, w14, eq | |
| ; CHECK-GI-NEXT: mov v1.h[2], w14 | |
| ; CHECK-GI-NEXT: eor v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: umov w14, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w15, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w16, v0.h[2] | |
| ; CHECK-GI-NEXT: and w14, w14, #0x1 | |
| ; CHECK-GI-NEXT: and w15, w15, #0x1 | |
| ; CHECK-GI-NEXT: and w16, w16, #0x1 | |
| ; CHECK-GI-NEXT: tst w14, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x10, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x13, x1, ne | |
| ; CHECK-GI-NEXT: tst w15, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x11, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x12, x3, ne | |
| ; CHECK-GI-NEXT: tst w16, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x8, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x9, x5, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i128>, <3 x i1>} @llvm.sadd.with.overflow(<3 x i128> %a, <3 x i128> %b) | |
| %e0 = extractvalue {<3 x i128>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i128>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i128> %e0, <3 x i128> %a | |
| ret <3 x i128> %r | |
| } | |
| define <3 x i128> @usub_v3i128(<3 x i128> %a, <3 x i128> %b) { | |
| ; CHECK-SD-LABEL: usub_v3i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp] | |
| ; CHECK-SD-NEXT: subs x8, x2, x8 | |
| ; CHECK-SD-NEXT: sbcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, lo | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #16] | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, lo | |
| ; CHECK-SD-NEXT: subs x8, x0, x6 | |
| ; CHECK-SD-NEXT: sbcs x11, x1, x7 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, lo | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, lo | |
| ; CHECK-SD-NEXT: subs x8, x4, x9 | |
| ; CHECK-SD-NEXT: sbcs x9, x5, x10 | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, lo | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, lo | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v3i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: ldp x8, x9, [sp] | |
| ; CHECK-GI-NEXT: subs x10, x0, x6 | |
| ; CHECK-GI-NEXT: ldp x11, x12, [sp, #16] | |
| ; CHECK-GI-NEXT: sbc x13, x1, x7 | |
| ; CHECK-GI-NEXT: subs x14, x2, x8 | |
| ; CHECK-GI-NEXT: sbc x15, x3, x9 | |
| ; CHECK-GI-NEXT: subs x16, x4, x11 | |
| ; CHECK-GI-NEXT: sbc x17, x5, x12 | |
| ; CHECK-GI-NEXT: cmp x0, x6 | |
| ; CHECK-GI-NEXT: cset w18, lo | |
| ; CHECK-GI-NEXT: cmp x1, x7 | |
| ; CHECK-GI-NEXT: cset w6, lo | |
| ; CHECK-GI-NEXT: csel w18, w18, w6, eq | |
| ; CHECK-GI-NEXT: cmp x2, x8 | |
| ; CHECK-GI-NEXT: cset w8, lo | |
| ; CHECK-GI-NEXT: cmp x3, x9 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: csel w8, w8, w9, eq | |
| ; CHECK-GI-NEXT: cmp x4, x11 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: cmp x5, x12 | |
| ; CHECK-GI-NEXT: cset w11, lo | |
| ; CHECK-GI-NEXT: csel w9, w9, w11, eq | |
| ; CHECK-GI-NEXT: tst w18, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x10, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x13, x1, ne | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x14, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x15, x3, ne | |
| ; CHECK-GI-NEXT: tst w9, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x16, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x17, x5, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i128>, <3 x i1>} @llvm.usub.with.overflow(<3 x i128> %a, <3 x i128> %b) | |
| %e0 = extractvalue {<3 x i128>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i128>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i128> %e0, <3 x i128> %a | |
| ret <3 x i128> %r | |
| } | |
| define <3 x i128> @ssub_v3i128(<3 x i128> %a, <3 x i128> %b) { | |
| ; CHECK-SD-LABEL: ssub_v3i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp] | |
| ; CHECK-SD-NEXT: subs x8, x2, x8 | |
| ; CHECK-SD-NEXT: sbcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, vs | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #16] | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, vs | |
| ; CHECK-SD-NEXT: subs x8, x0, x6 | |
| ; CHECK-SD-NEXT: sbcs x11, x1, x7 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, vs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, vs | |
| ; CHECK-SD-NEXT: subs x8, x4, x9 | |
| ; CHECK-SD-NEXT: sbcs x9, x5, x10 | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, vs | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, vs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v3i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: ldp x14, x15, [sp] | |
| ; CHECK-GI-NEXT: subs x10, x0, x6 | |
| ; CHECK-GI-NEXT: ldp x16, x17, [sp, #16] | |
| ; CHECK-GI-NEXT: sbc x13, x1, x7 | |
| ; CHECK-GI-NEXT: subs x11, x2, x14 | |
| ; CHECK-GI-NEXT: sbc x12, x3, x15 | |
| ; CHECK-GI-NEXT: subs x8, x4, x16 | |
| ; CHECK-GI-NEXT: sbc x9, x5, x17 | |
| ; CHECK-GI-NEXT: cmp x0, x6 | |
| ; CHECK-GI-NEXT: cset w18, lo | |
| ; CHECK-GI-NEXT: cmp x1, x7 | |
| ; CHECK-GI-NEXT: cset w6, lt | |
| ; CHECK-GI-NEXT: csel w18, w18, w6, eq | |
| ; CHECK-GI-NEXT: cmp x2, x14 | |
| ; CHECK-GI-NEXT: cset w14, lo | |
| ; CHECK-GI-NEXT: cmp x3, x15 | |
| ; CHECK-GI-NEXT: fmov s0, w18 | |
| ; CHECK-GI-NEXT: cset w15, lt | |
| ; CHECK-GI-NEXT: csel w14, w14, w15, eq | |
| ; CHECK-GI-NEXT: cmp x4, x16 | |
| ; CHECK-GI-NEXT: cset w15, lo | |
| ; CHECK-GI-NEXT: cmp x5, x17 | |
| ; CHECK-GI-NEXT: mov v0.h[1], w14 | |
| ; CHECK-GI-NEXT: cset w16, lt | |
| ; CHECK-GI-NEXT: csel w15, w15, w16, eq | |
| ; CHECK-GI-NEXT: cmp x13, #0 | |
| ; CHECK-GI-NEXT: cset w16, mi | |
| ; CHECK-GI-NEXT: csel w16, wzr, w16, eq | |
| ; CHECK-GI-NEXT: cmp x12, #0 | |
| ; CHECK-GI-NEXT: mov v0.h[2], w15 | |
| ; CHECK-GI-NEXT: fmov s1, w16 | |
| ; CHECK-GI-NEXT: cset w17, mi | |
| ; CHECK-GI-NEXT: csel w16, wzr, w17, eq | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: cset w14, mi | |
| ; CHECK-GI-NEXT: mov v1.h[1], w16 | |
| ; CHECK-GI-NEXT: csel w14, wzr, w14, eq | |
| ; CHECK-GI-NEXT: mov v1.h[2], w14 | |
| ; CHECK-GI-NEXT: eor v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: umov w14, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w15, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w16, v0.h[2] | |
| ; CHECK-GI-NEXT: and w14, w14, #0x1 | |
| ; CHECK-GI-NEXT: and w15, w15, #0x1 | |
| ; CHECK-GI-NEXT: and w16, w16, #0x1 | |
| ; CHECK-GI-NEXT: tst w14, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x10, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x13, x1, ne | |
| ; CHECK-GI-NEXT: tst w15, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x11, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x12, x3, ne | |
| ; CHECK-GI-NEXT: tst w16, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x8, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x9, x5, ne | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i128>, <3 x i1>} @llvm.ssub.with.overflow(<3 x i128> %a, <3 x i128> %b) | |
| %e0 = extractvalue {<3 x i128>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i128>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i128> %e0, <3 x i128> %a | |
| ret <3 x i128> %r | |
| } | |
| define <3 x i128> @umul_v3i128(<3 x i128> %a, <3 x i128> %b) { | |
| ; CHECK-SD-LABEL: umul_v3i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: stp x20, x19, [sp, #-16]! // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: .cfi_def_cfa_offset 16 | |
| ; CHECK-SD-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-SD-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp, #32] | |
| ; CHECK-SD-NEXT: cmp x5, #0 | |
| ; CHECK-SD-NEXT: ldp x16, x13, [sp, #16] | |
| ; CHECK-SD-NEXT: umulh x20, x7, x0 | |
| ; CHECK-SD-NEXT: mul x11, x9, x4 | |
| ; CHECK-SD-NEXT: ccmp x9, #0, #4, ne | |
| ; CHECK-SD-NEXT: umulh x12, x5, x8 | |
| ; CHECK-SD-NEXT: umulh x10, x9, x4 | |
| ; CHECK-SD-NEXT: madd x11, x5, x8, x11 | |
| ; CHECK-SD-NEXT: ccmp xzr, x12, #0, eq | |
| ; CHECK-SD-NEXT: umulh x14, x4, x8 | |
| ; CHECK-SD-NEXT: ccmp xzr, x10, #0, eq | |
| ; CHECK-SD-NEXT: mul x17, x13, x2 | |
| ; CHECK-SD-NEXT: cset w10, ne | |
| ; CHECK-SD-NEXT: umulh x18, x3, x16 | |
| ; CHECK-SD-NEXT: adds x11, x14, x11 | |
| ; CHECK-SD-NEXT: umulh x15, x13, x2 | |
| ; CHECK-SD-NEXT: csinc w10, w10, wzr, lo | |
| ; CHECK-SD-NEXT: cmp x3, #0 | |
| ; CHECK-SD-NEXT: ccmp x13, #0, #4, ne | |
| ; CHECK-SD-NEXT: madd x17, x3, x16, x17 | |
| ; CHECK-SD-NEXT: ccmp xzr, x18, #0, eq | |
| ; CHECK-SD-NEXT: umulh x19, x2, x16 | |
| ; CHECK-SD-NEXT: ccmp xzr, x15, #0, eq | |
| ; CHECK-SD-NEXT: mul x9, x7, x0 | |
| ; CHECK-SD-NEXT: cset w14, ne | |
| ; CHECK-SD-NEXT: umulh x12, x1, x6 | |
| ; CHECK-SD-NEXT: adds x15, x19, x17 | |
| ; CHECK-SD-NEXT: madd x9, x1, x6, x9 | |
| ; CHECK-SD-NEXT: csinc w14, w14, wzr, lo | |
| ; CHECK-SD-NEXT: cmp x1, #0 | |
| ; CHECK-SD-NEXT: ccmp x7, #0, #4, ne | |
| ; CHECK-SD-NEXT: umulh x13, x0, x6 | |
| ; CHECK-SD-NEXT: ccmp xzr, x12, #0, eq | |
| ; CHECK-SD-NEXT: mul x12, x0, x6 | |
| ; CHECK-SD-NEXT: ccmp xzr, x20, #0, eq | |
| ; CHECK-SD-NEXT: cset w17, ne | |
| ; CHECK-SD-NEXT: mul x16, x2, x16 | |
| ; CHECK-SD-NEXT: adds x9, x13, x9 | |
| ; CHECK-SD-NEXT: mul x8, x4, x8 | |
| ; CHECK-SD-NEXT: csinc w13, w17, wzr, lo | |
| ; CHECK-SD-NEXT: cmp w13, #0 | |
| ; CHECK-SD-NEXT: csel x0, x12, x0, ne | |
| ; CHECK-SD-NEXT: csel x1, x9, x1, ne | |
| ; CHECK-SD-NEXT: cmp w14, #0 | |
| ; CHECK-SD-NEXT: csel x2, x16, x2, ne | |
| ; CHECK-SD-NEXT: csel x3, x15, x3, ne | |
| ; CHECK-SD-NEXT: cmp w10, #0 | |
| ; CHECK-SD-NEXT: csel x5, x11, x5, ne | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, ne | |
| ; CHECK-SD-NEXT: ldp x20, x19, [sp], #16 // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v3i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub sp, sp, #128 | |
| ; CHECK-GI-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x28, x27, [sp, #48] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x26, x25, [sp, #64] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x24, x23, [sp, #80] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #96] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #112] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 128 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-GI-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-GI-NEXT: .cfi_offset w25, -56 | |
| ; CHECK-GI-NEXT: .cfi_offset w26, -64 | |
| ; CHECK-GI-NEXT: .cfi_offset w27, -72 | |
| ; CHECK-GI-NEXT: .cfi_offset w28, -80 | |
| ; CHECK-GI-NEXT: .cfi_offset w30, -88 | |
| ; CHECK-GI-NEXT: .cfi_offset w29, -96 | |
| ; CHECK-GI-NEXT: umulh x9, x0, xzr | |
| ; CHECK-GI-NEXT: ldp x10, x30, [sp, #128] | |
| ; CHECK-GI-NEXT: ldp x12, x17, [sp, #144] | |
| ; CHECK-GI-NEXT: umulh x13, x0, x6 | |
| ; CHECK-GI-NEXT: mul x15, x0, x7 | |
| ; CHECK-GI-NEXT: umulh x8, x6, xzr | |
| ; CHECK-GI-NEXT: mul x14, x1, x6 | |
| ; CHECK-GI-NEXT: umulh x18, x1, x6 | |
| ; CHECK-GI-NEXT: stp x8, x9, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: umulh x19, x0, x7 | |
| ; CHECK-GI-NEXT: mul x16, x1, x7 | |
| ; CHECK-GI-NEXT: umulh x9, x1, x7 | |
| ; CHECK-GI-NEXT: madd x7, x0, x7, x13 | |
| ; CHECK-GI-NEXT: adds x13, x13, x15 | |
| ; CHECK-GI-NEXT: cset w15, hs | |
| ; CHECK-GI-NEXT: cmn x13, x14 | |
| ; CHECK-GI-NEXT: umulh x24, x2, x10 | |
| ; CHECK-GI-NEXT: cset w13, hs | |
| ; CHECK-GI-NEXT: adds x14, x18, x19 | |
| ; CHECK-GI-NEXT: and x15, x15, #0x1 | |
| ; CHECK-GI-NEXT: and x13, x13, #0x1 | |
| ; CHECK-GI-NEXT: mul x26, x2, x30 | |
| ; CHECK-GI-NEXT: add x13, x15, x13 | |
| ; CHECK-GI-NEXT: cset w15, hs | |
| ; CHECK-GI-NEXT: adds x14, x14, x16 | |
| ; CHECK-GI-NEXT: mul x25, x3, x10 | |
| ; CHECK-GI-NEXT: cset w16, hs | |
| ; CHECK-GI-NEXT: adds x21, x14, x13 | |
| ; CHECK-GI-NEXT: cset w14, hs | |
| ; CHECK-GI-NEXT: umulh x8, x2, xzr | |
| ; CHECK-GI-NEXT: and x14, x14, #0x1 | |
| ; CHECK-GI-NEXT: umulh x27, x3, x10 | |
| ; CHECK-GI-NEXT: umulh x29, x2, x30 | |
| ; CHECK-GI-NEXT: stp x8, x9, [sp] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: mul x28, x3, x30 | |
| ; CHECK-GI-NEXT: umulh x23, x3, x30 | |
| ; CHECK-GI-NEXT: madd x30, x2, x30, x24 | |
| ; CHECK-GI-NEXT: adds x24, x24, x26 | |
| ; CHECK-GI-NEXT: cset w26, hs | |
| ; CHECK-GI-NEXT: cmn x24, x25 | |
| ; CHECK-GI-NEXT: umulh x20, x4, x12 | |
| ; CHECK-GI-NEXT: cset w24, hs | |
| ; CHECK-GI-NEXT: and x25, x26, #0x1 | |
| ; CHECK-GI-NEXT: and x24, x24, #0x1 | |
| ; CHECK-GI-NEXT: mul x8, x4, x17 | |
| ; CHECK-GI-NEXT: add x24, x25, x24 | |
| ; CHECK-GI-NEXT: adds x25, x27, x29 | |
| ; CHECK-GI-NEXT: cset w27, hs | |
| ; CHECK-GI-NEXT: adds x25, x25, x28 | |
| ; CHECK-GI-NEXT: mul x11, x5, x12 | |
| ; CHECK-GI-NEXT: cset w29, hs | |
| ; CHECK-GI-NEXT: adds x24, x25, x24 | |
| ; CHECK-GI-NEXT: cset w25, hs | |
| ; CHECK-GI-NEXT: umulh x22, x10, xzr | |
| ; CHECK-GI-NEXT: adds x8, x20, x8 | |
| ; CHECK-GI-NEXT: cset w9, hs | |
| ; CHECK-GI-NEXT: umulh x18, x5, x12 | |
| ; CHECK-GI-NEXT: cmn x8, x11 | |
| ; CHECK-GI-NEXT: and x8, x15, #0x1 | |
| ; CHECK-GI-NEXT: and x11, x16, #0x1 | |
| ; CHECK-GI-NEXT: add x8, x8, x11 | |
| ; CHECK-GI-NEXT: ldp x16, x11, [sp, #8] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: add x8, x8, x14 | |
| ; CHECK-GI-NEXT: ldr x14, [sp, #24] // 8-byte Reload | |
| ; CHECK-GI-NEXT: umulh x19, x4, x17 | |
| ; CHECK-GI-NEXT: and x9, x9, #0x1 | |
| ; CHECK-GI-NEXT: add x11, x11, x16 | |
| ; CHECK-GI-NEXT: mul x26, x5, x17 | |
| ; CHECK-GI-NEXT: and x16, x29, #0x1 | |
| ; CHECK-GI-NEXT: add x11, x11, x14 | |
| ; CHECK-GI-NEXT: add x8, x11, x8 | |
| ; CHECK-GI-NEXT: and x11, x27, #0x1 | |
| ; CHECK-GI-NEXT: umulh x28, x12, xzr | |
| ; CHECK-GI-NEXT: add x11, x11, x16 | |
| ; CHECK-GI-NEXT: and x16, x25, #0x1 | |
| ; CHECK-GI-NEXT: orr x8, x21, x8 | |
| ; CHECK-GI-NEXT: umulh x13, x5, x17 | |
| ; CHECK-GI-NEXT: add x11, x11, x16 | |
| ; CHECK-GI-NEXT: add x16, x22, x23 | |
| ; CHECK-GI-NEXT: cset w22, hs | |
| ; CHECK-GI-NEXT: adds x18, x18, x19 | |
| ; CHECK-GI-NEXT: ldr x23, [sp] // 8-byte Reload | |
| ; CHECK-GI-NEXT: umulh x15, x4, xzr | |
| ; CHECK-GI-NEXT: and x22, x22, #0x1 | |
| ; CHECK-GI-NEXT: cset w19, hs | |
| ; CHECK-GI-NEXT: add x9, x9, x22 | |
| ; CHECK-GI-NEXT: adds x18, x18, x26 | |
| ; CHECK-GI-NEXT: and x19, x19, #0x1 | |
| ; CHECK-GI-NEXT: madd x7, x1, x6, x7 | |
| ; CHECK-GI-NEXT: add x16, x16, x23 | |
| ; CHECK-GI-NEXT: add x13, x28, x13 | |
| ; CHECK-GI-NEXT: add x11, x16, x11 | |
| ; CHECK-GI-NEXT: mul x14, x0, x6 | |
| ; CHECK-GI-NEXT: orr x11, x24, x11 | |
| ; CHECK-GI-NEXT: add x13, x13, x15 | |
| ; CHECK-GI-NEXT: ldp x24, x23, [sp, #80] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: madd x17, x4, x17, x20 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: adds x9, x18, x9 | |
| ; CHECK-GI-NEXT: and x18, x20, #0x1 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: cmp x8, #0 | |
| ; CHECK-GI-NEXT: madd x6, x3, x10, x30 | |
| ; CHECK-GI-NEXT: add x18, x19, x18 | |
| ; CHECK-GI-NEXT: and x19, x20, #0x1 | |
| ; CHECK-GI-NEXT: add x18, x18, x19 | |
| ; CHECK-GI-NEXT: csel x0, x14, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x7, x1, ne | |
| ; CHECK-GI-NEXT: mul x10, x2, x10 | |
| ; CHECK-GI-NEXT: add x13, x13, x18 | |
| ; CHECK-GI-NEXT: cmp x11, #0 | |
| ; CHECK-GI-NEXT: orr x9, x9, x13 | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #112] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: mul x22, x4, x12 | |
| ; CHECK-GI-NEXT: ldp x26, x25, [sp, #64] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x3, x6, x3, ne | |
| ; CHECK-GI-NEXT: ldp x28, x27, [sp, #48] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: madd x12, x5, x12, x17 | |
| ; CHECK-GI-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: csel x4, x22, x4, ne | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #96] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x5, x12, x5, ne | |
| ; CHECK-GI-NEXT: add sp, sp, #128 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i128>, <3 x i1>} @llvm.umul.with.overflow(<3 x i128> %a, <3 x i128> %b) | |
| %e0 = extractvalue {<3 x i128>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i128>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i128> %e0, <3 x i128> %a | |
| ret <3 x i128> %r | |
| } | |
| define <3 x i128> @smul_v3i128(<3 x i128> %a, <3 x i128> %b) { | |
| ; CHECK-SD-LABEL: smul_v3i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: str x29, [sp, #-96]! // 8-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x28, x27, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x26, x25, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x24, x23, [sp, #48] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x22, x21, [sp, #64] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x20, x19, [sp, #80] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: .cfi_def_cfa_offset 96 | |
| ; CHECK-SD-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-SD-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-SD-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-SD-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-SD-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-SD-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-SD-NEXT: .cfi_offset w25, -56 | |
| ; CHECK-SD-NEXT: .cfi_offset w26, -64 | |
| ; CHECK-SD-NEXT: .cfi_offset w27, -72 | |
| ; CHECK-SD-NEXT: .cfi_offset w28, -80 | |
| ; CHECK-SD-NEXT: .cfi_offset w29, -96 | |
| ; CHECK-SD-NEXT: ldp x8, x13, [sp, #112] | |
| ; CHECK-SD-NEXT: asr x9, x5, #63 | |
| ; CHECK-SD-NEXT: asr x20, x3, #63 | |
| ; CHECK-SD-NEXT: asr x28, x1, #63 | |
| ; CHECK-SD-NEXT: umulh x29, x1, x6 | |
| ; CHECK-SD-NEXT: mul x11, x9, x8 | |
| ; CHECK-SD-NEXT: asr x9, x13, #63 | |
| ; CHECK-SD-NEXT: umulh x12, x4, x8 | |
| ; CHECK-SD-NEXT: mul x14, x5, x8 | |
| ; CHECK-SD-NEXT: umulh x10, x5, x8 | |
| ; CHECK-SD-NEXT: mul x17, x4, x13 | |
| ; CHECK-SD-NEXT: adds x12, x14, x12 | |
| ; CHECK-SD-NEXT: umulh x15, x4, x13 | |
| ; CHECK-SD-NEXT: adc x11, x10, x11 | |
| ; CHECK-SD-NEXT: mul x16, x4, x9 | |
| ; CHECK-SD-NEXT: ldp x9, x22, [sp, #96] | |
| ; CHECK-SD-NEXT: adds x10, x17, x12 | |
| ; CHECK-SD-NEXT: smulh x18, x5, x13 | |
| ; CHECK-SD-NEXT: asr x25, x22, #63 | |
| ; CHECK-SD-NEXT: mul x13, x5, x13 | |
| ; CHECK-SD-NEXT: adc x12, x15, x16 | |
| ; CHECK-SD-NEXT: asr x16, x11, #63 | |
| ; CHECK-SD-NEXT: umulh x21, x2, x9 | |
| ; CHECK-SD-NEXT: asr x17, x12, #63 | |
| ; CHECK-SD-NEXT: adds x11, x11, x12 | |
| ; CHECK-SD-NEXT: mul x23, x3, x9 | |
| ; CHECK-SD-NEXT: adc x16, x16, x17 | |
| ; CHECK-SD-NEXT: adds x11, x13, x11 | |
| ; CHECK-SD-NEXT: umulh x19, x3, x9 | |
| ; CHECK-SD-NEXT: adc x13, x18, x16 | |
| ; CHECK-SD-NEXT: mul x20, x20, x9 | |
| ; CHECK-SD-NEXT: adds x16, x23, x21 | |
| ; CHECK-SD-NEXT: mul x26, x2, x22 | |
| ; CHECK-SD-NEXT: umulh x24, x2, x22 | |
| ; CHECK-SD-NEXT: adc x18, x19, x20 | |
| ; CHECK-SD-NEXT: asr x19, x7, #63 | |
| ; CHECK-SD-NEXT: mul x25, x2, x25 | |
| ; CHECK-SD-NEXT: asr x23, x18, #63 | |
| ; CHECK-SD-NEXT: adds x16, x26, x16 | |
| ; CHECK-SD-NEXT: smulh x27, x3, x22 | |
| ; CHECK-SD-NEXT: mul x22, x3, x22 | |
| ; CHECK-SD-NEXT: adc x21, x24, x25 | |
| ; CHECK-SD-NEXT: ldp x26, x25, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: umulh x15, x0, x6 | |
| ; CHECK-SD-NEXT: asr x24, x21, #63 | |
| ; CHECK-SD-NEXT: adds x18, x18, x21 | |
| ; CHECK-SD-NEXT: mul x12, x1, x6 | |
| ; CHECK-SD-NEXT: adc x21, x23, x24 | |
| ; CHECK-SD-NEXT: adds x18, x22, x18 | |
| ; CHECK-SD-NEXT: ldp x24, x23, [sp, #48] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: mul x14, x28, x6 | |
| ; CHECK-SD-NEXT: adc x21, x27, x21 | |
| ; CHECK-SD-NEXT: ldp x28, x27, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: mul x20, x0, x7 | |
| ; CHECK-SD-NEXT: adds x12, x12, x15 | |
| ; CHECK-SD-NEXT: umulh x17, x0, x7 | |
| ; CHECK-SD-NEXT: adc x14, x29, x14 | |
| ; CHECK-SD-NEXT: mul x19, x0, x19 | |
| ; CHECK-SD-NEXT: adds x12, x20, x12 | |
| ; CHECK-SD-NEXT: asr x20, x14, #63 | |
| ; CHECK-SD-NEXT: mul x15, x1, x7 | |
| ; CHECK-SD-NEXT: smulh x7, x1, x7 | |
| ; CHECK-SD-NEXT: adc x17, x17, x19 | |
| ; CHECK-SD-NEXT: asr x19, x10, #63 | |
| ; CHECK-SD-NEXT: asr x22, x17, #63 | |
| ; CHECK-SD-NEXT: adds x14, x14, x17 | |
| ; CHECK-SD-NEXT: mul x6, x0, x6 | |
| ; CHECK-SD-NEXT: eor x13, x13, x19 | |
| ; CHECK-SD-NEXT: eor x11, x11, x19 | |
| ; CHECK-SD-NEXT: adc x17, x20, x22 | |
| ; CHECK-SD-NEXT: adds x14, x15, x14 | |
| ; CHECK-SD-NEXT: asr x15, x12, #63 | |
| ; CHECK-SD-NEXT: mul x9, x2, x9 | |
| ; CHECK-SD-NEXT: adc x17, x7, x17 | |
| ; CHECK-SD-NEXT: asr x7, x16, #63 | |
| ; CHECK-SD-NEXT: eor x17, x17, x15 | |
| ; CHECK-SD-NEXT: eor x14, x14, x15 | |
| ; CHECK-SD-NEXT: orr x11, x11, x13 | |
| ; CHECK-SD-NEXT: mul x8, x4, x8 | |
| ; CHECK-SD-NEXT: eor x15, x21, x7 | |
| ; CHECK-SD-NEXT: eor x18, x18, x7 | |
| ; CHECK-SD-NEXT: orr x14, x14, x17 | |
| ; CHECK-SD-NEXT: orr x13, x18, x15 | |
| ; CHECK-SD-NEXT: cmp x14, #0 | |
| ; CHECK-SD-NEXT: ldp x20, x19, [sp, #80] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: csel x0, x6, x0, ne | |
| ; CHECK-SD-NEXT: csel x1, x12, x1, ne | |
| ; CHECK-SD-NEXT: cmp x13, #0 | |
| ; CHECK-SD-NEXT: ldp x22, x21, [sp, #64] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: csel x2, x9, x2, ne | |
| ; CHECK-SD-NEXT: csel x3, x16, x3, ne | |
| ; CHECK-SD-NEXT: cmp x11, #0 | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, ne | |
| ; CHECK-SD-NEXT: csel x5, x10, x5, ne | |
| ; CHECK-SD-NEXT: ldr x29, [sp], #96 // 8-byte Folded Reload | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v3i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub sp, sp, #128 | |
| ; CHECK-GI-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x28, x27, [sp, #48] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x26, x25, [sp, #64] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x24, x23, [sp, #80] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #96] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #112] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 128 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-GI-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-GI-NEXT: .cfi_offset w25, -56 | |
| ; CHECK-GI-NEXT: .cfi_offset w26, -64 | |
| ; CHECK-GI-NEXT: .cfi_offset w27, -72 | |
| ; CHECK-GI-NEXT: .cfi_offset w28, -80 | |
| ; CHECK-GI-NEXT: .cfi_offset w30, -88 | |
| ; CHECK-GI-NEXT: .cfi_offset w29, -96 | |
| ; CHECK-GI-NEXT: mul x9, x0, x7 | |
| ; CHECK-GI-NEXT: asr x12, x1, #63 | |
| ; CHECK-GI-NEXT: asr x13, x7, #63 | |
| ; CHECK-GI-NEXT: ldp x10, x21, [sp, #128] | |
| ; CHECK-GI-NEXT: mul x8, x1, x6 | |
| ; CHECK-GI-NEXT: umulh x15, x1, x7 | |
| ; CHECK-GI-NEXT: asr x22, x21, #63 | |
| ; CHECK-GI-NEXT: umulh x16, x0, x13 | |
| ; CHECK-GI-NEXT: stp x9, x8, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: umulh x8, x12, x6 | |
| ; CHECK-GI-NEXT: umulh x23, x3, x21 | |
| ; CHECK-GI-NEXT: umulh x24, x2, x22 | |
| ; CHECK-GI-NEXT: add x8, x8, x15 | |
| ; CHECK-GI-NEXT: asr x15, x3, #63 | |
| ; CHECK-GI-NEXT: add x8, x8, x16 | |
| ; CHECK-GI-NEXT: mul x19, x0, x13 | |
| ; CHECK-GI-NEXT: madd x8, x0, x13, x8 | |
| ; CHECK-GI-NEXT: umulh x17, x15, x10 | |
| ; CHECK-GI-NEXT: madd x8, x1, x13, x8 | |
| ; CHECK-GI-NEXT: mul x16, x12, x6 | |
| ; CHECK-GI-NEXT: madd x13, x12, x7, x8 | |
| ; CHECK-GI-NEXT: umulh x11, x0, x6 | |
| ; CHECK-GI-NEXT: madd x9, x12, x6, x13 | |
| ; CHECK-GI-NEXT: add x12, x17, x23 | |
| ; CHECK-GI-NEXT: add x12, x12, x24 | |
| ; CHECK-GI-NEXT: madd x12, x2, x22, x12 | |
| ; CHECK-GI-NEXT: mul x24, x2, x22 | |
| ; CHECK-GI-NEXT: madd x12, x3, x22, x12 | |
| ; CHECK-GI-NEXT: asr x22, x5, #63 | |
| ; CHECK-GI-NEXT: umulh x14, x1, x6 | |
| ; CHECK-GI-NEXT: madd x12, x15, x21, x12 | |
| ; CHECK-GI-NEXT: umulh x20, x0, x7 | |
| ; CHECK-GI-NEXT: madd x8, x15, x10, x12 | |
| ; CHECK-GI-NEXT: ldp x12, x17, [sp, #144] | |
| ; CHECK-GI-NEXT: mul x18, x1, x7 | |
| ; CHECK-GI-NEXT: asr x28, x17, #63 | |
| ; CHECK-GI-NEXT: umulh x27, x22, x12 | |
| ; CHECK-GI-NEXT: stp x8, x9, [sp] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: ldp x8, x13, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: umulh x29, x5, x17 | |
| ; CHECK-GI-NEXT: umulh x30, x4, x28 | |
| ; CHECK-GI-NEXT: madd x7, x0, x7, x11 | |
| ; CHECK-GI-NEXT: adds x11, x11, x8 | |
| ; CHECK-GI-NEXT: cset w8, hs | |
| ; CHECK-GI-NEXT: cmn x11, x13 | |
| ; CHECK-GI-NEXT: add x27, x27, x29 | |
| ; CHECK-GI-NEXT: umulh x25, x2, x10 | |
| ; CHECK-GI-NEXT: cset w11, hs | |
| ; CHECK-GI-NEXT: adds x14, x14, x20 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: adds x14, x14, x19 | |
| ; CHECK-GI-NEXT: add x27, x27, x30 | |
| ; CHECK-GI-NEXT: mul x26, x2, x21 | |
| ; CHECK-GI-NEXT: and x8, x8, #0x1 | |
| ; CHECK-GI-NEXT: and x20, x20, #0x1 | |
| ; CHECK-GI-NEXT: mul x9, x3, x10 | |
| ; CHECK-GI-NEXT: mul x23, x15, x10 | |
| ; CHECK-GI-NEXT: umulh x15, x3, x10 | |
| ; CHECK-GI-NEXT: umulh x29, x2, x21 | |
| ; CHECK-GI-NEXT: mul x30, x3, x21 | |
| ; CHECK-GI-NEXT: madd x19, x2, x21, x25 | |
| ; CHECK-GI-NEXT: cset w21, hs | |
| ; CHECK-GI-NEXT: adds x14, x14, x18 | |
| ; CHECK-GI-NEXT: and x18, x11, #0x1 | |
| ; CHECK-GI-NEXT: and x21, x21, #0x1 | |
| ; CHECK-GI-NEXT: madd x27, x4, x28, x27 | |
| ; CHECK-GI-NEXT: add x8, x8, x18 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: adds x14, x14, x16 | |
| ; CHECK-GI-NEXT: add x20, x20, x21 | |
| ; CHECK-GI-NEXT: and x18, x18, #0x1 | |
| ; CHECK-GI-NEXT: cset w16, hs | |
| ; CHECK-GI-NEXT: adds x8, x14, x8 | |
| ; CHECK-GI-NEXT: umulh x13, x4, x12 | |
| ; CHECK-GI-NEXT: cset w11, hs | |
| ; CHECK-GI-NEXT: adds x25, x25, x26 | |
| ; CHECK-GI-NEXT: str x8, [sp, #24] // 8-byte Spill | |
| ; CHECK-GI-NEXT: madd x27, x5, x28, x27 | |
| ; CHECK-GI-NEXT: cset w26, hs | |
| ; CHECK-GI-NEXT: cmn x25, x9 | |
| ; CHECK-GI-NEXT: cset w25, hs | |
| ; CHECK-GI-NEXT: adds x15, x15, x29 | |
| ; CHECK-GI-NEXT: add x18, x20, x18 | |
| ; CHECK-GI-NEXT: mul x8, x4, x17 | |
| ; CHECK-GI-NEXT: and x25, x25, #0x1 | |
| ; CHECK-GI-NEXT: and x16, x16, #0x1 | |
| ; CHECK-GI-NEXT: and x11, x11, #0x1 | |
| ; CHECK-GI-NEXT: mul x14, x4, x28 | |
| ; CHECK-GI-NEXT: cset w28, hs | |
| ; CHECK-GI-NEXT: adds x15, x15, x24 | |
| ; CHECK-GI-NEXT: madd x24, x22, x17, x27 | |
| ; CHECK-GI-NEXT: cset w27, hs | |
| ; CHECK-GI-NEXT: adds x15, x15, x30 | |
| ; CHECK-GI-NEXT: cset w29, hs | |
| ; CHECK-GI-NEXT: adds x15, x15, x23 | |
| ; CHECK-GI-NEXT: and x23, x26, #0x1 | |
| ; CHECK-GI-NEXT: mul x30, x5, x12 | |
| ; CHECK-GI-NEXT: add x21, x23, x25 | |
| ; CHECK-GI-NEXT: cset w23, hs | |
| ; CHECK-GI-NEXT: adds x15, x15, x21 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: adds x8, x13, x8 | |
| ; CHECK-GI-NEXT: umulh x26, x5, x12 | |
| ; CHECK-GI-NEXT: cset w25, hs | |
| ; CHECK-GI-NEXT: umulh x21, x4, x17 | |
| ; CHECK-GI-NEXT: cmn x8, x30 | |
| ; CHECK-GI-NEXT: add x8, x18, x16 | |
| ; CHECK-GI-NEXT: and x16, x28, #0x1 | |
| ; CHECK-GI-NEXT: and x18, x27, #0x1 | |
| ; CHECK-GI-NEXT: add x8, x8, x11 | |
| ; CHECK-GI-NEXT: mul x9, x5, x17 | |
| ; CHECK-GI-NEXT: add x11, x16, x18 | |
| ; CHECK-GI-NEXT: and x16, x29, #0x1 | |
| ; CHECK-GI-NEXT: add x11, x11, x16 | |
| ; CHECK-GI-NEXT: and x16, x23, #0x1 | |
| ; CHECK-GI-NEXT: mul x18, x22, x12 | |
| ; CHECK-GI-NEXT: add x11, x11, x16 | |
| ; CHECK-GI-NEXT: and x16, x20, #0x1 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: madd x24, x22, x12, x24 | |
| ; CHECK-GI-NEXT: and x22, x25, #0x1 | |
| ; CHECK-GI-NEXT: and x20, x20, #0x1 | |
| ; CHECK-GI-NEXT: add x11, x11, x16 | |
| ; CHECK-GI-NEXT: add x16, x22, x20 | |
| ; CHECK-GI-NEXT: adds x20, x26, x21 | |
| ; CHECK-GI-NEXT: cset w21, hs | |
| ; CHECK-GI-NEXT: adds x14, x20, x14 | |
| ; CHECK-GI-NEXT: madd x13, x4, x17, x13 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: adds x9, x14, x9 | |
| ; CHECK-GI-NEXT: and x17, x21, #0x1 | |
| ; CHECK-GI-NEXT: and x14, x20, #0x1 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: adds x9, x9, x18 | |
| ; CHECK-GI-NEXT: add x14, x17, x14 | |
| ; CHECK-GI-NEXT: and x17, x20, #0x1 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: adds x9, x9, x16 | |
| ; CHECK-GI-NEXT: madd x7, x1, x6, x7 | |
| ; CHECK-GI-NEXT: add x14, x14, x17 | |
| ; CHECK-GI-NEXT: and x16, x18, #0x1 | |
| ; CHECK-GI-NEXT: cset w17, hs | |
| ; CHECK-GI-NEXT: madd x19, x3, x10, x19 | |
| ; CHECK-GI-NEXT: add x14, x14, x16 | |
| ; CHECK-GI-NEXT: and x16, x17, #0x1 | |
| ; CHECK-GI-NEXT: add x14, x14, x16 | |
| ; CHECK-GI-NEXT: ldr x16, [sp, #24] // 8-byte Reload | |
| ; CHECK-GI-NEXT: mul x17, x0, x6 | |
| ; CHECK-GI-NEXT: ldp x18, x6, [sp] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: eor x16, x16, x7, asr #63 | |
| ; CHECK-GI-NEXT: add x14, x24, x14 | |
| ; CHECK-GI-NEXT: madd x13, x5, x12, x13 | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #96] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: add x8, x6, x8 | |
| ; CHECK-GI-NEXT: add x11, x18, x11 | |
| ; CHECK-GI-NEXT: eor x15, x15, x19, asr #63 | |
| ; CHECK-GI-NEXT: eor x8, x8, x7, asr #63 | |
| ; CHECK-GI-NEXT: mul x10, x2, x10 | |
| ; CHECK-GI-NEXT: eor x11, x11, x19, asr #63 | |
| ; CHECK-GI-NEXT: ldp x24, x23, [sp, #80] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: mul x12, x4, x12 | |
| ; CHECK-GI-NEXT: orr x8, x16, x8 | |
| ; CHECK-GI-NEXT: orr x11, x15, x11 | |
| ; CHECK-GI-NEXT: eor x9, x9, x13, asr #63 | |
| ; CHECK-GI-NEXT: eor x14, x14, x13, asr #63 | |
| ; CHECK-GI-NEXT: cmp x8, #0 | |
| ; CHECK-GI-NEXT: csel x0, x17, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x7, x1, ne | |
| ; CHECK-GI-NEXT: cmp x11, #0 | |
| ; CHECK-GI-NEXT: orr x9, x9, x14 | |
| ; CHECK-GI-NEXT: csel x3, x19, x3, ne | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #112] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: ldp x26, x25, [sp, #64] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x4, x12, x4, ne | |
| ; CHECK-GI-NEXT: ldp x28, x27, [sp, #48] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x5, x13, x5, ne | |
| ; CHECK-GI-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: add sp, sp, #128 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<3 x i128>, <3 x i1>} @llvm.smul.with.overflow(<3 x i128> %a, <3 x i128> %b) | |
| %e0 = extractvalue {<3 x i128>, <3 x i1>} %o, 0 | |
| %e1 = extractvalue {<3 x i128>, <3 x i1>} %o, 1 | |
| %r = select <3 x i1> %e1, <3 x i128> %e0, <3 x i128> %a | |
| ret <3 x i128> %r | |
| } | |
| define <4 x i128> @uadd_v4i128(<4 x i128> %a, <4 x i128> %b) { | |
| ; CHECK-SD-LABEL: uadd_v4i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp, #16] | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp, #32] | |
| ; CHECK-SD-NEXT: adds x8, x2, x8 | |
| ; CHECK-SD-NEXT: adcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, hs | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, hs | |
| ; CHECK-SD-NEXT: adds x8, x4, x10 | |
| ; CHECK-SD-NEXT: adcs x9, x5, x11 | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp] | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, hs | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, hs | |
| ; CHECK-SD-NEXT: adds x8, x0, x10 | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #48] | |
| ; CHECK-SD-NEXT: adcs x11, x1, x11 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, hs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, hs | |
| ; CHECK-SD-NEXT: adds x8, x6, x9 | |
| ; CHECK-SD-NEXT: adcs x9, x7, x10 | |
| ; CHECK-SD-NEXT: csel x6, x8, x6, hs | |
| ; CHECK-SD-NEXT: csel x7, x9, x7, hs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: uadd_v4i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: str x23, [sp, #-48]! // 8-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 48 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -48 | |
| ; CHECK-GI-NEXT: ldp x8, x9, [sp, #48] | |
| ; CHECK-GI-NEXT: ldp x10, x11, [sp, #64] | |
| ; CHECK-GI-NEXT: ldp x12, x13, [sp, #80] | |
| ; CHECK-GI-NEXT: adds x14, x0, x8 | |
| ; CHECK-GI-NEXT: ldp x17, x18, [sp, #96] | |
| ; CHECK-GI-NEXT: adc x15, x1, x9 | |
| ; CHECK-GI-NEXT: adds x16, x2, x10 | |
| ; CHECK-GI-NEXT: adc x19, x3, x11 | |
| ; CHECK-GI-NEXT: adds x20, x4, x12 | |
| ; CHECK-GI-NEXT: adc x21, x5, x13 | |
| ; CHECK-GI-NEXT: adds x22, x6, x17 | |
| ; CHECK-GI-NEXT: adc x23, x7, x18 | |
| ; CHECK-GI-NEXT: cmp x14, x8 | |
| ; CHECK-GI-NEXT: cset w8, lo | |
| ; CHECK-GI-NEXT: cmp x15, x9 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: csel w8, w8, w9, eq | |
| ; CHECK-GI-NEXT: cmp x16, x10 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: cmp x19, x11 | |
| ; CHECK-GI-NEXT: cset w10, lo | |
| ; CHECK-GI-NEXT: csel w9, w9, w10, eq | |
| ; CHECK-GI-NEXT: cmp x20, x12 | |
| ; CHECK-GI-NEXT: cset w10, lo | |
| ; CHECK-GI-NEXT: cmp x21, x13 | |
| ; CHECK-GI-NEXT: cset w11, lo | |
| ; CHECK-GI-NEXT: csel w10, w10, w11, eq | |
| ; CHECK-GI-NEXT: cmp x22, x17 | |
| ; CHECK-GI-NEXT: cset w11, lo | |
| ; CHECK-GI-NEXT: cmp x23, x18 | |
| ; CHECK-GI-NEXT: cset w12, lo | |
| ; CHECK-GI-NEXT: csel w11, w11, w12, eq | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x14, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x15, x1, ne | |
| ; CHECK-GI-NEXT: tst w9, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x16, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x19, x3, ne | |
| ; CHECK-GI-NEXT: tst w10, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x20, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x21, x5, ne | |
| ; CHECK-GI-NEXT: tst w11, #0x1 | |
| ; CHECK-GI-NEXT: csel x6, x22, x6, ne | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x7, x23, x7, ne | |
| ; CHECK-GI-NEXT: ldr x23, [sp], #48 // 8-byte Folded Reload | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i128>, <4 x i1>} @llvm.uadd.with.overflow(<4 x i128> %a, <4 x i128> %b) | |
| %e0 = extractvalue {<4 x i128>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i128>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i128> %e0, <4 x i128> %a | |
| ret <4 x i128> %r | |
| } | |
| define <4 x i128> @sadd_v4i128(<4 x i128> %a, <4 x i128> %b) { | |
| ; CHECK-SD-LABEL: sadd_v4i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp, #16] | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp, #32] | |
| ; CHECK-SD-NEXT: adds x8, x2, x8 | |
| ; CHECK-SD-NEXT: adcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, vs | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, vs | |
| ; CHECK-SD-NEXT: adds x8, x4, x10 | |
| ; CHECK-SD-NEXT: adcs x9, x5, x11 | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp] | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, vs | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, vs | |
| ; CHECK-SD-NEXT: adds x8, x0, x10 | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #48] | |
| ; CHECK-SD-NEXT: adcs x11, x1, x11 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, vs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, vs | |
| ; CHECK-SD-NEXT: adds x8, x6, x9 | |
| ; CHECK-SD-NEXT: adcs x9, x7, x10 | |
| ; CHECK-SD-NEXT: csel x6, x8, x6, vs | |
| ; CHECK-SD-NEXT: csel x7, x9, x7, vs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: sadd_v4i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: stp x24, x23, [sp, #-48]! // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 48 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-GI-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-GI-NEXT: ldp x8, x18, [sp, #48] | |
| ; CHECK-GI-NEXT: ldp x9, x19, [sp, #64] | |
| ; CHECK-GI-NEXT: ldp x11, x16, [sp, #80] | |
| ; CHECK-GI-NEXT: adds x13, x0, x8 | |
| ; CHECK-GI-NEXT: ldp x8, x17, [sp, #96] | |
| ; CHECK-GI-NEXT: adc x14, x1, x18 | |
| ; CHECK-GI-NEXT: adds x10, x2, x9 | |
| ; CHECK-GI-NEXT: adc x15, x3, x19 | |
| ; CHECK-GI-NEXT: adds x11, x4, x11 | |
| ; CHECK-GI-NEXT: adc x12, x5, x16 | |
| ; CHECK-GI-NEXT: adds x8, x6, x8 | |
| ; CHECK-GI-NEXT: adc x9, x7, x17 | |
| ; CHECK-GI-NEXT: cmp x13, x0 | |
| ; CHECK-GI-NEXT: cset w20, lo | |
| ; CHECK-GI-NEXT: cmp x14, x1 | |
| ; CHECK-GI-NEXT: cset w21, lt | |
| ; CHECK-GI-NEXT: csel w20, w20, w21, eq | |
| ; CHECK-GI-NEXT: cmp x10, x2 | |
| ; CHECK-GI-NEXT: cset w21, lo | |
| ; CHECK-GI-NEXT: cmp x15, x3 | |
| ; CHECK-GI-NEXT: fmov s0, w20 | |
| ; CHECK-GI-NEXT: cset w22, lt | |
| ; CHECK-GI-NEXT: csel w21, w21, w22, eq | |
| ; CHECK-GI-NEXT: cmp x11, x4 | |
| ; CHECK-GI-NEXT: cset w22, lo | |
| ; CHECK-GI-NEXT: cmp x12, x5 | |
| ; CHECK-GI-NEXT: mov v0.h[1], w21 | |
| ; CHECK-GI-NEXT: cset w23, lt | |
| ; CHECK-GI-NEXT: csel w22, w22, w23, eq | |
| ; CHECK-GI-NEXT: cmp x8, x6 | |
| ; CHECK-GI-NEXT: cset w23, lo | |
| ; CHECK-GI-NEXT: cmp x9, x7 | |
| ; CHECK-GI-NEXT: cset w24, lt | |
| ; CHECK-GI-NEXT: mov v0.h[2], w22 | |
| ; CHECK-GI-NEXT: csel w23, w23, w24, eq | |
| ; CHECK-GI-NEXT: cmp x18, #0 | |
| ; CHECK-GI-NEXT: cset w18, mi | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel w18, wzr, w18, eq | |
| ; CHECK-GI-NEXT: cmp x19, #0 | |
| ; CHECK-GI-NEXT: fmov s1, w18 | |
| ; CHECK-GI-NEXT: cset w19, mi | |
| ; CHECK-GI-NEXT: mov v0.h[3], w23 | |
| ; CHECK-GI-NEXT: csel w18, wzr, w19, eq | |
| ; CHECK-GI-NEXT: cmp x16, #0 | |
| ; CHECK-GI-NEXT: cset w16, mi | |
| ; CHECK-GI-NEXT: mov v1.h[1], w18 | |
| ; CHECK-GI-NEXT: csel w16, wzr, w16, eq | |
| ; CHECK-GI-NEXT: cmp x17, #0 | |
| ; CHECK-GI-NEXT: mov v1.h[2], w16 | |
| ; CHECK-GI-NEXT: cset w16, mi | |
| ; CHECK-GI-NEXT: csel w16, wzr, w16, eq | |
| ; CHECK-GI-NEXT: mov v1.h[3], w16 | |
| ; CHECK-GI-NEXT: eor v0.8b, v1.8b, v0.8b | |
| ; CHECK-GI-NEXT: umov w16, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w17, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w18, v0.h[2] | |
| ; CHECK-GI-NEXT: umov w19, v0.h[3] | |
| ; CHECK-GI-NEXT: and w16, w16, #0x1 | |
| ; CHECK-GI-NEXT: and w17, w17, #0x1 | |
| ; CHECK-GI-NEXT: and w18, w18, #0x1 | |
| ; CHECK-GI-NEXT: tst w16, #0x1 | |
| ; CHECK-GI-NEXT: and w19, w19, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x13, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x14, x1, ne | |
| ; CHECK-GI-NEXT: tst w17, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x15, x3, ne | |
| ; CHECK-GI-NEXT: tst w18, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x11, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x12, x5, ne | |
| ; CHECK-GI-NEXT: tst w19, #0x1 | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x6, x8, x6, ne | |
| ; CHECK-GI-NEXT: csel x7, x9, x7, ne | |
| ; CHECK-GI-NEXT: ldp x24, x23, [sp], #48 // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i128>, <4 x i1>} @llvm.sadd.with.overflow(<4 x i128> %a, <4 x i128> %b) | |
| %e0 = extractvalue {<4 x i128>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i128>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i128> %e0, <4 x i128> %a | |
| ret <4 x i128> %r | |
| } | |
| define <4 x i128> @usub_v4i128(<4 x i128> %a, <4 x i128> %b) { | |
| ; CHECK-SD-LABEL: usub_v4i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp, #16] | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp, #32] | |
| ; CHECK-SD-NEXT: subs x8, x2, x8 | |
| ; CHECK-SD-NEXT: sbcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, lo | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, lo | |
| ; CHECK-SD-NEXT: subs x8, x4, x10 | |
| ; CHECK-SD-NEXT: sbcs x9, x5, x11 | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp] | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, lo | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, lo | |
| ; CHECK-SD-NEXT: subs x8, x0, x10 | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #48] | |
| ; CHECK-SD-NEXT: sbcs x11, x1, x11 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, lo | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, lo | |
| ; CHECK-SD-NEXT: subs x8, x6, x9 | |
| ; CHECK-SD-NEXT: sbcs x9, x7, x10 | |
| ; CHECK-SD-NEXT: csel x6, x8, x6, lo | |
| ; CHECK-SD-NEXT: csel x7, x9, x7, lo | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: usub_v4i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: str x23, [sp, #-48]! // 8-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 48 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -48 | |
| ; CHECK-GI-NEXT: ldp x8, x9, [sp, #48] | |
| ; CHECK-GI-NEXT: ldp x10, x11, [sp, #64] | |
| ; CHECK-GI-NEXT: ldp x12, x13, [sp, #80] | |
| ; CHECK-GI-NEXT: subs x14, x0, x8 | |
| ; CHECK-GI-NEXT: ldp x17, x18, [sp, #96] | |
| ; CHECK-GI-NEXT: sbc x15, x1, x9 | |
| ; CHECK-GI-NEXT: subs x16, x2, x10 | |
| ; CHECK-GI-NEXT: sbc x19, x3, x11 | |
| ; CHECK-GI-NEXT: subs x20, x4, x12 | |
| ; CHECK-GI-NEXT: sbc x21, x5, x13 | |
| ; CHECK-GI-NEXT: subs x22, x6, x17 | |
| ; CHECK-GI-NEXT: sbc x23, x7, x18 | |
| ; CHECK-GI-NEXT: cmp x0, x8 | |
| ; CHECK-GI-NEXT: cset w8, lo | |
| ; CHECK-GI-NEXT: cmp x1, x9 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: csel w8, w8, w9, eq | |
| ; CHECK-GI-NEXT: cmp x2, x10 | |
| ; CHECK-GI-NEXT: cset w9, lo | |
| ; CHECK-GI-NEXT: cmp x3, x11 | |
| ; CHECK-GI-NEXT: cset w10, lo | |
| ; CHECK-GI-NEXT: csel w9, w9, w10, eq | |
| ; CHECK-GI-NEXT: cmp x4, x12 | |
| ; CHECK-GI-NEXT: cset w10, lo | |
| ; CHECK-GI-NEXT: cmp x5, x13 | |
| ; CHECK-GI-NEXT: cset w11, lo | |
| ; CHECK-GI-NEXT: csel w10, w10, w11, eq | |
| ; CHECK-GI-NEXT: cmp x6, x17 | |
| ; CHECK-GI-NEXT: cset w11, lo | |
| ; CHECK-GI-NEXT: cmp x7, x18 | |
| ; CHECK-GI-NEXT: cset w12, lo | |
| ; CHECK-GI-NEXT: csel w11, w11, w12, eq | |
| ; CHECK-GI-NEXT: tst w8, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x14, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x15, x1, ne | |
| ; CHECK-GI-NEXT: tst w9, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x16, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x19, x3, ne | |
| ; CHECK-GI-NEXT: tst w10, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x20, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x21, x5, ne | |
| ; CHECK-GI-NEXT: tst w11, #0x1 | |
| ; CHECK-GI-NEXT: csel x6, x22, x6, ne | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x7, x23, x7, ne | |
| ; CHECK-GI-NEXT: ldr x23, [sp], #48 // 8-byte Folded Reload | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i128>, <4 x i1>} @llvm.usub.with.overflow(<4 x i128> %a, <4 x i128> %b) | |
| %e0 = extractvalue {<4 x i128>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i128>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i128> %e0, <4 x i128> %a | |
| ret <4 x i128> %r | |
| } | |
| define <4 x i128> @ssub_v4i128(<4 x i128> %a, <4 x i128> %b) { | |
| ; CHECK-SD-LABEL: ssub_v4i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: ldp x8, x9, [sp, #16] | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp, #32] | |
| ; CHECK-SD-NEXT: subs x8, x2, x8 | |
| ; CHECK-SD-NEXT: sbcs x9, x3, x9 | |
| ; CHECK-SD-NEXT: csel x3, x9, x3, vs | |
| ; CHECK-SD-NEXT: csel x2, x8, x2, vs | |
| ; CHECK-SD-NEXT: subs x8, x4, x10 | |
| ; CHECK-SD-NEXT: sbcs x9, x5, x11 | |
| ; CHECK-SD-NEXT: ldp x10, x11, [sp] | |
| ; CHECK-SD-NEXT: csel x4, x8, x4, vs | |
| ; CHECK-SD-NEXT: csel x5, x9, x5, vs | |
| ; CHECK-SD-NEXT: subs x8, x0, x10 | |
| ; CHECK-SD-NEXT: ldp x9, x10, [sp, #48] | |
| ; CHECK-SD-NEXT: sbcs x11, x1, x11 | |
| ; CHECK-SD-NEXT: csel x1, x11, x1, vs | |
| ; CHECK-SD-NEXT: csel x0, x8, x0, vs | |
| ; CHECK-SD-NEXT: subs x8, x6, x9 | |
| ; CHECK-SD-NEXT: sbcs x9, x7, x10 | |
| ; CHECK-SD-NEXT: csel x6, x8, x6, vs | |
| ; CHECK-SD-NEXT: csel x7, x9, x7, vs | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: ssub_v4i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: str x23, [sp, #-48]! // 8-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 48 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -48 | |
| ; CHECK-GI-NEXT: ldp x16, x17, [sp, #48] | |
| ; CHECK-GI-NEXT: ldp x18, x19, [sp, #64] | |
| ; CHECK-GI-NEXT: ldp x20, x21, [sp, #80] | |
| ; CHECK-GI-NEXT: subs x13, x0, x16 | |
| ; CHECK-GI-NEXT: ldp x22, x23, [sp, #96] | |
| ; CHECK-GI-NEXT: sbc x14, x1, x17 | |
| ; CHECK-GI-NEXT: subs x10, x2, x18 | |
| ; CHECK-GI-NEXT: sbc x15, x3, x19 | |
| ; CHECK-GI-NEXT: subs x11, x4, x20 | |
| ; CHECK-GI-NEXT: sbc x12, x5, x21 | |
| ; CHECK-GI-NEXT: subs x8, x6, x22 | |
| ; CHECK-GI-NEXT: sbc x9, x7, x23 | |
| ; CHECK-GI-NEXT: cmp x0, x16 | |
| ; CHECK-GI-NEXT: cset w16, lo | |
| ; CHECK-GI-NEXT: cmp x1, x17 | |
| ; CHECK-GI-NEXT: cset w17, lt | |
| ; CHECK-GI-NEXT: csel w16, w16, w17, eq | |
| ; CHECK-GI-NEXT: cmp x2, x18 | |
| ; CHECK-GI-NEXT: cset w17, lo | |
| ; CHECK-GI-NEXT: cmp x3, x19 | |
| ; CHECK-GI-NEXT: fmov s0, w16 | |
| ; CHECK-GI-NEXT: cset w18, lt | |
| ; CHECK-GI-NEXT: csel w17, w17, w18, eq | |
| ; CHECK-GI-NEXT: cmp x4, x20 | |
| ; CHECK-GI-NEXT: cset w18, lo | |
| ; CHECK-GI-NEXT: cmp x5, x21 | |
| ; CHECK-GI-NEXT: mov v0.h[1], w17 | |
| ; CHECK-GI-NEXT: cset w19, lt | |
| ; CHECK-GI-NEXT: csel w18, w18, w19, eq | |
| ; CHECK-GI-NEXT: cmp x6, x22 | |
| ; CHECK-GI-NEXT: cset w19, lo | |
| ; CHECK-GI-NEXT: cmp x7, x23 | |
| ; CHECK-GI-NEXT: cset w20, lt | |
| ; CHECK-GI-NEXT: mov v0.h[2], w18 | |
| ; CHECK-GI-NEXT: csel w19, w19, w20, eq | |
| ; CHECK-GI-NEXT: cmp x14, #0 | |
| ; CHECK-GI-NEXT: cset w20, mi | |
| ; CHECK-GI-NEXT: csel w20, wzr, w20, eq | |
| ; CHECK-GI-NEXT: cmp x15, #0 | |
| ; CHECK-GI-NEXT: fmov s1, w20 | |
| ; CHECK-GI-NEXT: cset w21, mi | |
| ; CHECK-GI-NEXT: mov v0.h[3], w19 | |
| ; CHECK-GI-NEXT: csel w16, wzr, w21, eq | |
| ; CHECK-GI-NEXT: cmp x12, #0 | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: mov v1.h[1], w16 | |
| ; CHECK-GI-NEXT: cset w16, mi | |
| ; CHECK-GI-NEXT: csel w16, wzr, w16, eq | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: mov v1.h[2], w16 | |
| ; CHECK-GI-NEXT: cset w16, mi | |
| ; CHECK-GI-NEXT: csel w16, wzr, w16, eq | |
| ; CHECK-GI-NEXT: mov v1.h[3], w16 | |
| ; CHECK-GI-NEXT: eor v0.8b, v0.8b, v1.8b | |
| ; CHECK-GI-NEXT: umov w16, v0.h[0] | |
| ; CHECK-GI-NEXT: umov w17, v0.h[1] | |
| ; CHECK-GI-NEXT: umov w18, v0.h[2] | |
| ; CHECK-GI-NEXT: umov w19, v0.h[3] | |
| ; CHECK-GI-NEXT: and w16, w16, #0x1 | |
| ; CHECK-GI-NEXT: and w17, w17, #0x1 | |
| ; CHECK-GI-NEXT: and w18, w18, #0x1 | |
| ; CHECK-GI-NEXT: tst w16, #0x1 | |
| ; CHECK-GI-NEXT: and w19, w19, #0x1 | |
| ; CHECK-GI-NEXT: csel x0, x13, x0, ne | |
| ; CHECK-GI-NEXT: csel x1, x14, x1, ne | |
| ; CHECK-GI-NEXT: tst w17, #0x1 | |
| ; CHECK-GI-NEXT: csel x2, x10, x2, ne | |
| ; CHECK-GI-NEXT: csel x3, x15, x3, ne | |
| ; CHECK-GI-NEXT: tst w18, #0x1 | |
| ; CHECK-GI-NEXT: csel x4, x11, x4, ne | |
| ; CHECK-GI-NEXT: csel x5, x12, x5, ne | |
| ; CHECK-GI-NEXT: tst w19, #0x1 | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x6, x8, x6, ne | |
| ; CHECK-GI-NEXT: csel x7, x9, x7, ne | |
| ; CHECK-GI-NEXT: ldr x23, [sp], #48 // 8-byte Folded Reload | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i128>, <4 x i1>} @llvm.ssub.with.overflow(<4 x i128> %a, <4 x i128> %b) | |
| %e0 = extractvalue {<4 x i128>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i128>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i128> %e0, <4 x i128> %a | |
| ret <4 x i128> %r | |
| } | |
| define <4 x i128> @umul_v4i128(<4 x i128> %a, <4 x i128> %b) { | |
| ; CHECK-SD-LABEL: umul_v4i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: str x25, [sp, #-64]! // 8-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x24, x23, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x22, x21, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x20, x19, [sp, #48] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: .cfi_def_cfa_offset 64 | |
| ; CHECK-SD-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-SD-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-SD-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-SD-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-SD-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-SD-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-SD-NEXT: .cfi_offset w25, -64 | |
| ; CHECK-SD-NEXT: ldp x8, x10, [sp, #112] | |
| ; CHECK-SD-NEXT: cmp x7, #0 | |
| ; CHECK-SD-NEXT: ldp x22, x19, [sp, #80] | |
| ; CHECK-SD-NEXT: mul x9, x10, x6 | |
| ; CHECK-SD-NEXT: ccmp x10, #0, #4, ne | |
| ; CHECK-SD-NEXT: umulh x12, x7, x8 | |
| ; CHECK-SD-NEXT: umulh x11, x10, x6 | |
| ; CHECK-SD-NEXT: ldp x25, x10, [sp, #64] | |
| ; CHECK-SD-NEXT: madd x13, x7, x8, x9 | |
| ; CHECK-SD-NEXT: ldp x9, x14, [sp, #96] | |
| ; CHECK-SD-NEXT: ccmp xzr, x12, #0, eq | |
| ; CHECK-SD-NEXT: umulh x15, x6, x8 | |
| ; CHECK-SD-NEXT: ccmp xzr, x11, #0, eq | |
| ; CHECK-SD-NEXT: mul x17, x14, x4 | |
| ; CHECK-SD-NEXT: cset w11, ne | |
| ; CHECK-SD-NEXT: umulh x18, x5, x9 | |
| ; CHECK-SD-NEXT: adds x13, x15, x13 | |
| ; CHECK-SD-NEXT: umulh x16, x14, x4 | |
| ; CHECK-SD-NEXT: csinc w11, w11, wzr, lo | |
| ; CHECK-SD-NEXT: cmp x5, #0 | |
| ; CHECK-SD-NEXT: ccmp x14, #0, #4, ne | |
| ; CHECK-SD-NEXT: madd x17, x5, x9, x17 | |
| ; CHECK-SD-NEXT: ccmp xzr, x18, #0, eq | |
| ; CHECK-SD-NEXT: umulh x20, x4, x9 | |
| ; CHECK-SD-NEXT: ccmp xzr, x16, #0, eq | |
| ; CHECK-SD-NEXT: mul x23, x19, x2 | |
| ; CHECK-SD-NEXT: cset w18, ne | |
| ; CHECK-SD-NEXT: umulh x24, x3, x22 | |
| ; CHECK-SD-NEXT: adds x17, x20, x17 | |
| ; CHECK-SD-NEXT: umulh x21, x19, x2 | |
| ; CHECK-SD-NEXT: csinc w18, w18, wzr, lo | |
| ; CHECK-SD-NEXT: cmp x3, #0 | |
| ; CHECK-SD-NEXT: ccmp x19, #0, #4, ne | |
| ; CHECK-SD-NEXT: madd x23, x3, x22, x23 | |
| ; CHECK-SD-NEXT: ccmp xzr, x24, #0, eq | |
| ; CHECK-SD-NEXT: umulh x12, x2, x22 | |
| ; CHECK-SD-NEXT: ccmp xzr, x21, #0, eq | |
| ; CHECK-SD-NEXT: mul x14, x10, x0 | |
| ; CHECK-SD-NEXT: cset w20, ne | |
| ; CHECK-SD-NEXT: umulh x16, x1, x25 | |
| ; CHECK-SD-NEXT: adds x12, x12, x23 | |
| ; CHECK-SD-NEXT: ldp x24, x23, [sp, #16] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: umulh x15, x10, x0 | |
| ; CHECK-SD-NEXT: csinc w20, w20, wzr, lo | |
| ; CHECK-SD-NEXT: cmp x1, #0 | |
| ; CHECK-SD-NEXT: ccmp x10, #0, #4, ne | |
| ; CHECK-SD-NEXT: madd x14, x1, x25, x14 | |
| ; CHECK-SD-NEXT: ccmp xzr, x16, #0, eq | |
| ; CHECK-SD-NEXT: umulh x19, x0, x25 | |
| ; CHECK-SD-NEXT: ccmp xzr, x15, #0, eq | |
| ; CHECK-SD-NEXT: mul x10, x0, x25 | |
| ; CHECK-SD-NEXT: cset w16, ne | |
| ; CHECK-SD-NEXT: mul x15, x2, x22 | |
| ; CHECK-SD-NEXT: ldp x22, x21, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: adds x14, x19, x14 | |
| ; CHECK-SD-NEXT: mul x9, x4, x9 | |
| ; CHECK-SD-NEXT: csinc w16, w16, wzr, lo | |
| ; CHECK-SD-NEXT: cmp w16, #0 | |
| ; CHECK-SD-NEXT: mul x8, x6, x8 | |
| ; CHECK-SD-NEXT: csel x0, x10, x0, ne | |
| ; CHECK-SD-NEXT: csel x1, x14, x1, ne | |
| ; CHECK-SD-NEXT: cmp w20, #0 | |
| ; CHECK-SD-NEXT: ldp x20, x19, [sp, #48] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: csel x2, x15, x2, ne | |
| ; CHECK-SD-NEXT: csel x3, x12, x3, ne | |
| ; CHECK-SD-NEXT: cmp w18, #0 | |
| ; CHECK-SD-NEXT: csel x4, x9, x4, ne | |
| ; CHECK-SD-NEXT: csel x5, x17, x5, ne | |
| ; CHECK-SD-NEXT: cmp w11, #0 | |
| ; CHECK-SD-NEXT: csel x7, x13, x7, ne | |
| ; CHECK-SD-NEXT: csel x6, x8, x6, ne | |
| ; CHECK-SD-NEXT: ldr x25, [sp], #64 // 8-byte Folded Reload | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: umul_v4i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub sp, sp, #208 | |
| ; CHECK-GI-NEXT: stp x29, x30, [sp, #112] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x28, x27, [sp, #128] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x26, x25, [sp, #144] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x24, x23, [sp, #160] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #176] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #192] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 208 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-GI-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-GI-NEXT: .cfi_offset w25, -56 | |
| ; CHECK-GI-NEXT: .cfi_offset w26, -64 | |
| ; CHECK-GI-NEXT: .cfi_offset w27, -72 | |
| ; CHECK-GI-NEXT: .cfi_offset w28, -80 | |
| ; CHECK-GI-NEXT: .cfi_offset w30, -88 | |
| ; CHECK-GI-NEXT: .cfi_offset w29, -96 | |
| ; CHECK-GI-NEXT: ldp x11, x19, [sp, #208] | |
| ; CHECK-GI-NEXT: mov x22, x2 | |
| ; CHECK-GI-NEXT: ldp x23, x25, [sp, #224] | |
| ; CHECK-GI-NEXT: mov x27, x6 | |
| ; CHECK-GI-NEXT: mov x21, x0 | |
| ; CHECK-GI-NEXT: mov x24, x4 | |
| ; CHECK-GI-NEXT: mov x28, x1 | |
| ; CHECK-GI-NEXT: umulh x9, x11, xzr | |
| ; CHECK-GI-NEXT: mov x17, x7 | |
| ; CHECK-GI-NEXT: umulh x8, x1, x19 | |
| ; CHECK-GI-NEXT: umulh x20, x2, x23 | |
| ; CHECK-GI-NEXT: mul x6, x2, x25 | |
| ; CHECK-GI-NEXT: stp x8, x9, [sp, #96] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: mul x9, x3, x25 | |
| ; CHECK-GI-NEXT: umulh x8, x3, x25 | |
| ; CHECK-GI-NEXT: umulh x18, x2, x25 | |
| ; CHECK-GI-NEXT: ldp x2, x30, [sp, #240] | |
| ; CHECK-GI-NEXT: umulh x14, x0, x11 | |
| ; CHECK-GI-NEXT: stp x9, x8, [sp, #80] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: mul x9, x4, x30 | |
| ; CHECK-GI-NEXT: umulh x8, x4, x30 | |
| ; CHECK-GI-NEXT: mul x15, x0, x19 | |
| ; CHECK-GI-NEXT: umulh x16, x0, x19 | |
| ; CHECK-GI-NEXT: stp x8, x9, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: mul x8, x21, x11 | |
| ; CHECK-GI-NEXT: mul x0, x1, x19 | |
| ; CHECK-GI-NEXT: madd x19, x21, x19, x14 | |
| ; CHECK-GI-NEXT: adds x14, x14, x15 | |
| ; CHECK-GI-NEXT: stp x3, x8, [sp, #48] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: cset w15, hs | |
| ; CHECK-GI-NEXT: madd x29, x22, x25, x20 | |
| ; CHECK-GI-NEXT: and x15, x15, #0x1 | |
| ; CHECK-GI-NEXT: madd x9, x1, x11, x19 | |
| ; CHECK-GI-NEXT: madd x8, x3, x23, x29 | |
| ; CHECK-GI-NEXT: mul x12, x1, x11 | |
| ; CHECK-GI-NEXT: umulh x26, x4, x2 | |
| ; CHECK-GI-NEXT: stp x8, x9, [sp, #64] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: umulh x8, x5, x30 | |
| ; CHECK-GI-NEXT: cmn x14, x12 | |
| ; CHECK-GI-NEXT: umulh x13, x1, x11 | |
| ; CHECK-GI-NEXT: mul x4, x5, x30 | |
| ; CHECK-GI-NEXT: str x8, [sp, #8] // 8-byte Spill | |
| ; CHECK-GI-NEXT: madd x8, x24, x30, x26 | |
| ; CHECK-GI-NEXT: mul x9, x3, x23 | |
| ; CHECK-GI-NEXT: umulh x10, x3, x23 | |
| ; CHECK-GI-NEXT: umulh x30, x23, xzr | |
| ; CHECK-GI-NEXT: mul x11, x22, x23 | |
| ; CHECK-GI-NEXT: cset w23, hs | |
| ; CHECK-GI-NEXT: adds x16, x13, x16 | |
| ; CHECK-GI-NEXT: and x23, x23, #0x1 | |
| ; CHECK-GI-NEXT: madd x8, x5, x2, x8 | |
| ; CHECK-GI-NEXT: add x15, x15, x23 | |
| ; CHECK-GI-NEXT: cset w23, hs | |
| ; CHECK-GI-NEXT: adds x16, x16, x0 | |
| ; CHECK-GI-NEXT: cset w0, hs | |
| ; CHECK-GI-NEXT: adds x29, x16, x15 | |
| ; CHECK-GI-NEXT: umulh x12, x5, x2 | |
| ; CHECK-GI-NEXT: cset w1, hs | |
| ; CHECK-GI-NEXT: adds x16, x20, x6 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: cmn x16, x9 | |
| ; CHECK-GI-NEXT: umulh x3, x21, xzr | |
| ; CHECK-GI-NEXT: stp x11, x8, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: cset w9, hs | |
| ; CHECK-GI-NEXT: ldr x8, [sp, #80] // 8-byte Reload | |
| ; CHECK-GI-NEXT: adds x10, x10, x18 | |
| ; CHECK-GI-NEXT: and x18, x20, #0x1 | |
| ; CHECK-GI-NEXT: and x9, x9, #0x1 | |
| ; CHECK-GI-NEXT: mul x11, x5, x2 | |
| ; CHECK-GI-NEXT: cset w15, hs | |
| ; CHECK-GI-NEXT: adds x10, x10, x8 | |
| ; CHECK-GI-NEXT: add x9, x18, x9 | |
| ; CHECK-GI-NEXT: cset w20, hs | |
| ; CHECK-GI-NEXT: and x1, x1, #0x1 | |
| ; CHECK-GI-NEXT: adds x25, x10, x9 | |
| ; CHECK-GI-NEXT: ldp x10, x8, [sp, #32] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldp x16, x18, [sp, #256] | |
| ; CHECK-GI-NEXT: cset w13, hs | |
| ; CHECK-GI-NEXT: umulh x7, x22, xzr | |
| ; CHECK-GI-NEXT: and x15, x15, #0x1 | |
| ; CHECK-GI-NEXT: and x20, x20, #0x1 | |
| ; CHECK-GI-NEXT: adds x26, x26, x8 | |
| ; CHECK-GI-NEXT: add x15, x15, x20 | |
| ; CHECK-GI-NEXT: and x13, x13, #0x1 | |
| ; CHECK-GI-NEXT: umulh x14, x27, x16 | |
| ; CHECK-GI-NEXT: cset w8, hs | |
| ; CHECK-GI-NEXT: cmn x26, x11 | |
| ; CHECK-GI-NEXT: cset w26, hs | |
| ; CHECK-GI-NEXT: and x8, x8, #0x1 | |
| ; CHECK-GI-NEXT: adds x12, x12, x10 | |
| ; CHECK-GI-NEXT: mul x11, x27, x18 | |
| ; CHECK-GI-NEXT: and x26, x26, #0x1 | |
| ; CHECK-GI-NEXT: add x8, x8, x26 | |
| ; CHECK-GI-NEXT: cset w26, hs | |
| ; CHECK-GI-NEXT: adds x12, x12, x4 | |
| ; CHECK-GI-NEXT: mul x9, x17, x16 | |
| ; CHECK-GI-NEXT: cset w10, hs | |
| ; CHECK-GI-NEXT: adds x19, x12, x8 | |
| ; CHECK-GI-NEXT: cset w12, hs | |
| ; CHECK-GI-NEXT: and x10, x10, #0x1 | |
| ; CHECK-GI-NEXT: umulh x4, x2, xzr | |
| ; CHECK-GI-NEXT: and x12, x12, #0x1 | |
| ; CHECK-GI-NEXT: adds x11, x14, x11 | |
| ; CHECK-GI-NEXT: cset w8, hs | |
| ; CHECK-GI-NEXT: umulh x6, x24, xzr | |
| ; CHECK-GI-NEXT: cmn x11, x9 | |
| ; CHECK-GI-NEXT: and x9, x23, #0x1 | |
| ; CHECK-GI-NEXT: and x11, x0, #0x1 | |
| ; CHECK-GI-NEXT: add x9, x9, x11 | |
| ; CHECK-GI-NEXT: ldp x23, x11, [sp, #96] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: umulh x0, x17, x16 | |
| ; CHECK-GI-NEXT: add x9, x9, x1 | |
| ; CHECK-GI-NEXT: ldr x1, [sp, #88] // 8-byte Reload | |
| ; CHECK-GI-NEXT: and x8, x8, #0x1 | |
| ; CHECK-GI-NEXT: add x11, x11, x23 | |
| ; CHECK-GI-NEXT: umulh x23, x27, x18 | |
| ; CHECK-GI-NEXT: add x1, x30, x1 | |
| ; CHECK-GI-NEXT: add x11, x11, x3 | |
| ; CHECK-GI-NEXT: mul x3, x17, x18 | |
| ; CHECK-GI-NEXT: add x9, x11, x9 | |
| ; CHECK-GI-NEXT: add x11, x15, x13 | |
| ; CHECK-GI-NEXT: add x13, x1, x7 | |
| ; CHECK-GI-NEXT: and x1, x26, #0x1 | |
| ; CHECK-GI-NEXT: orr x9, x29, x9 | |
| ; CHECK-GI-NEXT: add x11, x13, x11 | |
| ; CHECK-GI-NEXT: cset w13, hs | |
| ; CHECK-GI-NEXT: add x10, x1, x10 | |
| ; CHECK-GI-NEXT: adds x0, x0, x23 | |
| ; CHECK-GI-NEXT: and x13, x13, #0x1 | |
| ; CHECK-GI-NEXT: madd x14, x27, x18, x14 | |
| ; CHECK-GI-NEXT: add x8, x8, x13 | |
| ; CHECK-GI-NEXT: cset w13, hs | |
| ; CHECK-GI-NEXT: add x10, x10, x12 | |
| ; CHECK-GI-NEXT: adds x0, x0, x3 | |
| ; CHECK-GI-NEXT: umulh x15, x16, xzr | |
| ; CHECK-GI-NEXT: and x13, x13, #0x1 | |
| ; CHECK-GI-NEXT: cset w12, hs | |
| ; CHECK-GI-NEXT: adds x8, x0, x8 | |
| ; CHECK-GI-NEXT: ldr x0, [sp, #8] // 8-byte Reload | |
| ; CHECK-GI-NEXT: umulh x7, x17, x18 | |
| ; CHECK-GI-NEXT: and x12, x12, #0x1 | |
| ; CHECK-GI-NEXT: orr x11, x25, x11 | |
| ; CHECK-GI-NEXT: add x12, x13, x12 | |
| ; CHECK-GI-NEXT: cset w13, hs | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: umulh x1, x27, xzr | |
| ; CHECK-GI-NEXT: add x0, x4, x0 | |
| ; CHECK-GI-NEXT: and x13, x13, #0x1 | |
| ; CHECK-GI-NEXT: add x18, x0, x6 | |
| ; CHECK-GI-NEXT: add x12, x12, x13 | |
| ; CHECK-GI-NEXT: madd x9, x17, x16, x14 | |
| ; CHECK-GI-NEXT: ldr x14, [sp, #56] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x10, x18, x10 | |
| ; CHECK-GI-NEXT: add x15, x15, x7 | |
| ; CHECK-GI-NEXT: orr x10, x19, x10 | |
| ; CHECK-GI-NEXT: csel x0, x14, x21, ne | |
| ; CHECK-GI-NEXT: ldr x14, [sp, #72] // 8-byte Reload | |
| ; CHECK-GI-NEXT: mul x20, x24, x2 | |
| ; CHECK-GI-NEXT: add x13, x15, x1 | |
| ; CHECK-GI-NEXT: ldp x26, x25, [sp, #144] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x1, x14, x28, ne | |
| ; CHECK-GI-NEXT: cmp x11, #0 | |
| ; CHECK-GI-NEXT: ldr x11, [sp, #16] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x12, x13, x12 | |
| ; CHECK-GI-NEXT: mul x13, x27, x16 | |
| ; CHECK-GI-NEXT: ldr x14, [sp, #48] // 8-byte Reload | |
| ; CHECK-GI-NEXT: csel x2, x11, x22, ne | |
| ; CHECK-GI-NEXT: ldr x11, [sp, #64] // 8-byte Reload | |
| ; CHECK-GI-NEXT: orr x8, x8, x12 | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #176] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x3, x11, x14, ne | |
| ; CHECK-GI-NEXT: cmp x10, #0 | |
| ; CHECK-GI-NEXT: ldr x10, [sp, #24] // 8-byte Reload | |
| ; CHECK-GI-NEXT: csel x4, x20, x24, ne | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #192] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x5, x10, x5, ne | |
| ; CHECK-GI-NEXT: cmp x8, #0 | |
| ; CHECK-GI-NEXT: csel x6, x13, x27, ne | |
| ; CHECK-GI-NEXT: ldp x24, x23, [sp, #160] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldp x28, x27, [sp, #128] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x7, x9, x17, ne | |
| ; CHECK-GI-NEXT: ldp x29, x30, [sp, #112] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: add sp, sp, #208 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i128>, <4 x i1>} @llvm.umul.with.overflow(<4 x i128> %a, <4 x i128> %b) | |
| %e0 = extractvalue {<4 x i128>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i128>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i128> %e0, <4 x i128> %a | |
| ret <4 x i128> %r | |
| } | |
| define <4 x i128> @smul_v4i128(<4 x i128> %a, <4 x i128> %b) { | |
| ; CHECK-SD-LABEL: smul_v4i128: | |
| ; CHECK-SD: // %bb.0: | |
| ; CHECK-SD-NEXT: sub sp, sp, #160 | |
| ; CHECK-SD-NEXT: stp x29, x30, [sp, #64] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x28, x27, [sp, #80] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x26, x25, [sp, #96] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x24, x23, [sp, #112] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x22, x21, [sp, #128] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: stp x20, x19, [sp, #144] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: .cfi_def_cfa_offset 160 | |
| ; CHECK-SD-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-SD-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-SD-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-SD-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-SD-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-SD-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-SD-NEXT: .cfi_offset w25, -56 | |
| ; CHECK-SD-NEXT: .cfi_offset w26, -64 | |
| ; CHECK-SD-NEXT: .cfi_offset w27, -72 | |
| ; CHECK-SD-NEXT: .cfi_offset w28, -80 | |
| ; CHECK-SD-NEXT: .cfi_offset w30, -88 | |
| ; CHECK-SD-NEXT: .cfi_offset w29, -96 | |
| ; CHECK-SD-NEXT: mov x19, x7 | |
| ; CHECK-SD-NEXT: ldp x23, x20, [sp, #200] | |
| ; CHECK-SD-NEXT: asr x9, x19, #63 | |
| ; CHECK-SD-NEXT: mov x7, x6 | |
| ; CHECK-SD-NEXT: mov x6, x5 | |
| ; CHECK-SD-NEXT: ldp x26, x17, [sp, #184] | |
| ; CHECK-SD-NEXT: mov x5, x4 | |
| ; CHECK-SD-NEXT: mul x21, x9, x20 | |
| ; CHECK-SD-NEXT: ldr x9, [sp, #216] | |
| ; CHECK-SD-NEXT: mov x4, x3 | |
| ; CHECK-SD-NEXT: mov x3, x2 | |
| ; CHECK-SD-NEXT: mov x2, x1 | |
| ; CHECK-SD-NEXT: mov x1, x0 | |
| ; CHECK-SD-NEXT: mul x8, x19, x9 | |
| ; CHECK-SD-NEXT: asr x10, x9, #63 | |
| ; CHECK-SD-NEXT: asr x25, x4, #63 | |
| ; CHECK-SD-NEXT: ldr x14, [sp, #176] | |
| ; CHECK-SD-NEXT: asr x28, x26, #63 | |
| ; CHECK-SD-NEXT: mul x15, x7, x10 | |
| ; CHECK-SD-NEXT: asr x10, x6, #63 | |
| ; CHECK-SD-NEXT: umulh x13, x7, x9 | |
| ; CHECK-SD-NEXT: str x8, [sp, #48] // 8-byte Spill | |
| ; CHECK-SD-NEXT: mul x8, x10, x17 | |
| ; CHECK-SD-NEXT: asr x10, x23, #63 | |
| ; CHECK-SD-NEXT: mul x18, x7, x9 | |
| ; CHECK-SD-NEXT: smulh x30, x19, x9 | |
| ; CHECK-SD-NEXT: str x8, [sp, #56] // 8-byte Spill | |
| ; CHECK-SD-NEXT: umulh x9, x5, x23 | |
| ; CHECK-SD-NEXT: smulh x8, x6, x23 | |
| ; CHECK-SD-NEXT: umulh x11, x7, x20 | |
| ; CHECK-SD-NEXT: umulh x0, x19, x20 | |
| ; CHECK-SD-NEXT: stp x9, x8, [sp, #32] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: mul x9, x6, x23 | |
| ; CHECK-SD-NEXT: umulh x8, x3, x26 | |
| ; CHECK-SD-NEXT: mul x27, x25, x14 | |
| ; CHECK-SD-NEXT: umulh x12, x5, x17 | |
| ; CHECK-SD-NEXT: stp x8, x9, [sp, #16] // 16-byte Folded Spill | |
| ; CHECK-SD-NEXT: smulh x8, x4, x26 | |
| ; CHECK-SD-NEXT: mul x22, x5, x10 | |
| ; CHECK-SD-NEXT: umulh x16, x6, x17 | |
| ; CHECK-SD-NEXT: str x8, [sp, #8] // 8-byte Spill | |
| ; CHECK-SD-NEXT: mul x8, x19, x20 | |
| ; CHECK-SD-NEXT: mul x24, x5, x23 | |
| ; CHECK-SD-NEXT: mul x29, x3, x26 | |
| ; CHECK-SD-NEXT: adds x9, x8, x11 | |
| ; CHECK-SD-NEXT: adc x8, x0, x21 | |
| ; CHECK-SD-NEXT: adds x25, x18, x9 | |
| ; CHECK-SD-NEXT: mul x11, x6, x17 | |
| ; CHECK-SD-NEXT: adc x9, x13, x15 | |
| ; CHECK-SD-NEXT: asr x13, x8, #63 | |
| ; CHECK-SD-NEXT: asr x10, x9, #63 | |
| ; CHECK-SD-NEXT: adds x8, x8, x9 | |
| ; CHECK-SD-NEXT: ldr x9, [sp, #48] // 8-byte Reload | |
| ; CHECK-SD-NEXT: umulh x18, x3, x14 | |
| ; CHECK-SD-NEXT: adc x10, x13, x10 | |
| ; CHECK-SD-NEXT: adds x8, x9, x8 | |
| ; CHECK-SD-NEXT: ldr x13, [sp, #160] | |
| ; CHECK-SD-NEXT: str x8, [sp, #48] // 8-byte Spill | |
| ; CHECK-SD-NEXT: ldr x8, [sp, #56] // 8-byte Reload | |
| ; CHECK-SD-NEXT: adc x23, x30, x10 | |
| ; CHECK-SD-NEXT: adds x10, x11, x12 | |
| ; CHECK-SD-NEXT: mul x15, x4, x14 | |
| ; CHECK-SD-NEXT: asr x11, x2, #63 | |
| ; CHECK-SD-NEXT: adc x16, x16, x8 | |
| ; CHECK-SD-NEXT: ldp x9, x8, [sp, #24] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: adds x21, x24, x10 | |
| ; CHECK-SD-NEXT: umulh x0, x4, x14 | |
| ; CHECK-SD-NEXT: asr x24, x16, #63 | |
| ; CHECK-SD-NEXT: ldr x10, [sp, #40] // 8-byte Reload | |
| ; CHECK-SD-NEXT: adc x22, x8, x22 | |
| ; CHECK-SD-NEXT: mul x28, x3, x28 | |
| ; CHECK-SD-NEXT: asr x8, x22, #63 | |
| ; CHECK-SD-NEXT: adds x16, x16, x22 | |
| ; CHECK-SD-NEXT: mul x26, x4, x26 | |
| ; CHECK-SD-NEXT: adc x8, x24, x8 | |
| ; CHECK-SD-NEXT: adds x30, x9, x16 | |
| ; CHECK-SD-NEXT: ldr x24, [sp, #168] | |
| ; CHECK-SD-NEXT: adc x16, x10, x8 | |
| ; CHECK-SD-NEXT: adds x8, x15, x18 | |
| ; CHECK-SD-NEXT: umulh x22, x1, x13 | |
| ; CHECK-SD-NEXT: adc x15, x0, x27 | |
| ; CHECK-SD-NEXT: adds x10, x29, x8 | |
| ; CHECK-SD-NEXT: ldr x8, [sp, #16] // 8-byte Reload | |
| ; CHECK-SD-NEXT: mul x9, x2, x13 | |
| ; CHECK-SD-NEXT: asr x0, x15, #63 | |
| ; CHECK-SD-NEXT: asr x29, x24, #63 | |
| ; CHECK-SD-NEXT: adc x27, x8, x28 | |
| ; CHECK-SD-NEXT: umulh x12, x2, x13 | |
| ; CHECK-SD-NEXT: asr x28, x27, #63 | |
| ; CHECK-SD-NEXT: adds x15, x15, x27 | |
| ; CHECK-SD-NEXT: ldr x27, [sp, #8] // 8-byte Reload | |
| ; CHECK-SD-NEXT: mul x11, x11, x13 | |
| ; CHECK-SD-NEXT: adc x0, x0, x28 | |
| ; CHECK-SD-NEXT: adds x15, x26, x15 | |
| ; CHECK-SD-NEXT: adc x0, x27, x0 | |
| ; CHECK-SD-NEXT: asr x27, x25, #63 | |
| ; CHECK-SD-NEXT: adds x9, x9, x22 | |
| ; CHECK-SD-NEXT: mul x8, x1, x24 | |
| ; CHECK-SD-NEXT: umulh x18, x1, x24 | |
| ; CHECK-SD-NEXT: adc x11, x12, x11 | |
| ; CHECK-SD-NEXT: eor x12, x23, x27 | |
| ; CHECK-SD-NEXT: ldr x23, [sp, #48] // 8-byte Reload | |
| ; CHECK-SD-NEXT: mul x26, x1, x29 | |
| ; CHECK-SD-NEXT: adds x8, x8, x9 | |
| ; CHECK-SD-NEXT: eor x23, x23, x27 | |
| ; CHECK-SD-NEXT: mul x9, x2, x24 | |
| ; CHECK-SD-NEXT: orr x12, x23, x12 | |
| ; CHECK-SD-NEXT: asr x23, x10, #63 | |
| ; CHECK-SD-NEXT: smulh x22, x2, x24 | |
| ; CHECK-SD-NEXT: asr x24, x21, #63 | |
| ; CHECK-SD-NEXT: eor x0, x0, x23 | |
| ; CHECK-SD-NEXT: adc x18, x18, x26 | |
| ; CHECK-SD-NEXT: asr x26, x11, #63 | |
| ; CHECK-SD-NEXT: asr x27, x18, #63 | |
| ; CHECK-SD-NEXT: adds x11, x11, x18 | |
| ; CHECK-SD-NEXT: mul x13, x1, x13 | |
| ; CHECK-SD-NEXT: eor x16, x16, x24 | |
| ; CHECK-SD-NEXT: eor x24, x30, x24 | |
| ; CHECK-SD-NEXT: adc x18, x26, x27 | |
| ; CHECK-SD-NEXT: adds x9, x9, x11 | |
| ; CHECK-SD-NEXT: asr x11, x8, #63 | |
| ; CHECK-SD-NEXT: adc x18, x22, x18 | |
| ; CHECK-SD-NEXT: mul x14, x3, x14 | |
| ; CHECK-SD-NEXT: orr x16, x24, x16 | |
| ; CHECK-SD-NEXT: eor x18, x18, x11 | |
| ; CHECK-SD-NEXT: eor x9, x9, x11 | |
| ; CHECK-SD-NEXT: eor x11, x15, x23 | |
| ; CHECK-SD-NEXT: mul x17, x5, x17 | |
| ; CHECK-SD-NEXT: orr x9, x9, x18 | |
| ; CHECK-SD-NEXT: orr x11, x11, x0 | |
| ; CHECK-SD-NEXT: cmp x9, #0 | |
| ; CHECK-SD-NEXT: ldp x24, x23, [sp, #112] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: mul x15, x7, x20 | |
| ; CHECK-SD-NEXT: csel x0, x13, x1, ne | |
| ; CHECK-SD-NEXT: csel x1, x8, x2, ne | |
| ; CHECK-SD-NEXT: cmp x11, #0 | |
| ; CHECK-SD-NEXT: ldp x28, x27, [sp, #80] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: csel x2, x14, x3, ne | |
| ; CHECK-SD-NEXT: csel x3, x10, x4, ne | |
| ; CHECK-SD-NEXT: cmp x16, #0 | |
| ; CHECK-SD-NEXT: csel x4, x17, x5, ne | |
| ; CHECK-SD-NEXT: csel x5, x21, x6, ne | |
| ; CHECK-SD-NEXT: cmp x12, #0 | |
| ; CHECK-SD-NEXT: ldp x22, x21, [sp, #128] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: csel x6, x15, x7, ne | |
| ; CHECK-SD-NEXT: csel x7, x25, x19, ne | |
| ; CHECK-SD-NEXT: ldp x20, x19, [sp, #144] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: ldp x26, x25, [sp, #96] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: ldp x29, x30, [sp, #64] // 16-byte Folded Reload | |
| ; CHECK-SD-NEXT: add sp, sp, #160 | |
| ; CHECK-SD-NEXT: ret | |
| ; | |
| ; CHECK-GI-LABEL: smul_v4i128: | |
| ; CHECK-GI: // %bb.0: | |
| ; CHECK-GI-NEXT: sub sp, sp, #224 | |
| ; CHECK-GI-NEXT: stp x29, x30, [sp, #128] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x28, x27, [sp, #144] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x26, x25, [sp, #160] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x24, x23, [sp, #176] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x22, x21, [sp, #192] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: stp x20, x19, [sp, #208] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: .cfi_def_cfa_offset 224 | |
| ; CHECK-GI-NEXT: .cfi_offset w19, -8 | |
| ; CHECK-GI-NEXT: .cfi_offset w20, -16 | |
| ; CHECK-GI-NEXT: .cfi_offset w21, -24 | |
| ; CHECK-GI-NEXT: .cfi_offset w22, -32 | |
| ; CHECK-GI-NEXT: .cfi_offset w23, -40 | |
| ; CHECK-GI-NEXT: .cfi_offset w24, -48 | |
| ; CHECK-GI-NEXT: .cfi_offset w25, -56 | |
| ; CHECK-GI-NEXT: .cfi_offset w26, -64 | |
| ; CHECK-GI-NEXT: .cfi_offset w27, -72 | |
| ; CHECK-GI-NEXT: .cfi_offset w28, -80 | |
| ; CHECK-GI-NEXT: .cfi_offset w30, -88 | |
| ; CHECK-GI-NEXT: .cfi_offset w29, -96 | |
| ; CHECK-GI-NEXT: ldp x25, x8, [sp, #224] | |
| ; CHECK-GI-NEXT: asr x10, x1, #63 | |
| ; CHECK-GI-NEXT: mov x17, x5 | |
| ; CHECK-GI-NEXT: ldp x5, x19, [sp, #240] | |
| ; CHECK-GI-NEXT: mov x18, x1 | |
| ; CHECK-GI-NEXT: asr x26, x17, #63 | |
| ; CHECK-GI-NEXT: mov x11, x6 | |
| ; CHECK-GI-NEXT: asr x12, x8, #63 | |
| ; CHECK-GI-NEXT: umulh x9, x10, x25 | |
| ; CHECK-GI-NEXT: asr x6, x7, #63 | |
| ; CHECK-GI-NEXT: asr x16, x19, #63 | |
| ; CHECK-GI-NEXT: str x2, [sp, #72] // 8-byte Spill | |
| ; CHECK-GI-NEXT: umulh x13, x1, x8 | |
| ; CHECK-GI-NEXT: stp x18, x3, [sp, #8] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: str x0, [sp, #48] // 8-byte Spill | |
| ; CHECK-GI-NEXT: umulh x14, x0, x12 | |
| ; CHECK-GI-NEXT: umulh x20, x3, x19 | |
| ; CHECK-GI-NEXT: add x9, x9, x13 | |
| ; CHECK-GI-NEXT: asr x13, x3, #63 | |
| ; CHECK-GI-NEXT: umulh x22, x2, x16 | |
| ; CHECK-GI-NEXT: add x9, x9, x14 | |
| ; CHECK-GI-NEXT: madd x9, x0, x12, x9 | |
| ; CHECK-GI-NEXT: mul x14, x0, x12 | |
| ; CHECK-GI-NEXT: madd x9, x1, x12, x9 | |
| ; CHECK-GI-NEXT: mul x12, x10, x25 | |
| ; CHECK-GI-NEXT: umulh x15, x13, x5 | |
| ; CHECK-GI-NEXT: umulh x21, x0, x25 | |
| ; CHECK-GI-NEXT: str x12, [sp, #112] // 8-byte Spill | |
| ; CHECK-GI-NEXT: madd x12, x10, x8, x9 | |
| ; CHECK-GI-NEXT: madd x9, x10, x25, x12 | |
| ; CHECK-GI-NEXT: add x10, x15, x20 | |
| ; CHECK-GI-NEXT: add x10, x10, x22 | |
| ; CHECK-GI-NEXT: ldp x1, x22, [sp, #256] | |
| ; CHECK-GI-NEXT: madd x15, x2, x16, x10 | |
| ; CHECK-GI-NEXT: asr x23, x22, #63 | |
| ; CHECK-GI-NEXT: umulh x20, x26, x1 | |
| ; CHECK-GI-NEXT: str x9, [sp, #120] // 8-byte Spill | |
| ; CHECK-GI-NEXT: madd x15, x3, x16, x15 | |
| ; CHECK-GI-NEXT: mul x9, x2, x16 | |
| ; CHECK-GI-NEXT: umulh x24, x17, x22 | |
| ; CHECK-GI-NEXT: umulh x27, x4, x23 | |
| ; CHECK-GI-NEXT: stp x9, x14, [sp, #80] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: madd x15, x13, x19, x15 | |
| ; CHECK-GI-NEXT: add x16, x20, x24 | |
| ; CHECK-GI-NEXT: mov x24, x17 | |
| ; CHECK-GI-NEXT: mov x20, x4 | |
| ; CHECK-GI-NEXT: mul x10, x13, x5 | |
| ; CHECK-GI-NEXT: add x16, x16, x27 | |
| ; CHECK-GI-NEXT: madd x9, x13, x5, x15 | |
| ; CHECK-GI-NEXT: madd x16, x4, x23, x16 | |
| ; CHECK-GI-NEXT: mul x15, x2, x19 | |
| ; CHECK-GI-NEXT: str x9, [sp, #104] // 8-byte Spill | |
| ; CHECK-GI-NEXT: madd x16, x17, x23, x16 | |
| ; CHECK-GI-NEXT: mul x9, x4, x23 | |
| ; CHECK-GI-NEXT: ldp x14, x23, [sp, #272] | |
| ; CHECK-GI-NEXT: madd x13, x26, x22, x16 | |
| ; CHECK-GI-NEXT: ldr x16, [sp, #88] // 8-byte Reload | |
| ; CHECK-GI-NEXT: asr x29, x23, #63 | |
| ; CHECK-GI-NEXT: umulh x27, x6, x14 | |
| ; CHECK-GI-NEXT: stp x10, x9, [sp, #56] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: umulh x28, x7, x23 | |
| ; CHECK-GI-NEXT: umulh x30, x11, x29 | |
| ; CHECK-GI-NEXT: madd x9, x26, x1, x13 | |
| ; CHECK-GI-NEXT: add x27, x27, x28 | |
| ; CHECK-GI-NEXT: mul x10, x0, x8 | |
| ; CHECK-GI-NEXT: add x27, x27, x30 | |
| ; CHECK-GI-NEXT: madd x27, x11, x29, x27 | |
| ; CHECK-GI-NEXT: str x9, [sp, #96] // 8-byte Spill | |
| ; CHECK-GI-NEXT: umulh x13, x0, x8 | |
| ; CHECK-GI-NEXT: adds x10, x21, x10 | |
| ; CHECK-GI-NEXT: madd x30, x7, x29, x27 | |
| ; CHECK-GI-NEXT: mul x9, x11, x29 | |
| ; CHECK-GI-NEXT: mul x29, x18, x8 | |
| ; CHECK-GI-NEXT: madd x8, x0, x8, x21 | |
| ; CHECK-GI-NEXT: mul x28, x26, x1 | |
| ; CHECK-GI-NEXT: mov x26, x7 | |
| ; CHECK-GI-NEXT: mov x7, x11 | |
| ; CHECK-GI-NEXT: umulh x11, x2, x5 | |
| ; CHECK-GI-NEXT: stp x8, x9, [sp, #24] // 16-byte Folded Spill | |
| ; CHECK-GI-NEXT: mov x8, x2 | |
| ; CHECK-GI-NEXT: cset w9, hs | |
| ; CHECK-GI-NEXT: umulh x17, x2, x19 | |
| ; CHECK-GI-NEXT: and x9, x9, #0x1 | |
| ; CHECK-GI-NEXT: madd x8, x8, x19, x11 | |
| ; CHECK-GI-NEXT: mul x2, x3, x19 | |
| ; CHECK-GI-NEXT: mul x19, x18, x25 | |
| ; CHECK-GI-NEXT: str x8, [sp, #40] // 8-byte Spill | |
| ; CHECK-GI-NEXT: umulh x8, x18, x25 | |
| ; CHECK-GI-NEXT: ldr x18, [sp, #112] // 8-byte Reload | |
| ; CHECK-GI-NEXT: mul x12, x3, x5 | |
| ; CHECK-GI-NEXT: cmn x10, x19 | |
| ; CHECK-GI-NEXT: cset w10, hs | |
| ; CHECK-GI-NEXT: umulh x21, x3, x5 | |
| ; CHECK-GI-NEXT: adds x8, x8, x13 | |
| ; CHECK-GI-NEXT: and x10, x10, #0x1 | |
| ; CHECK-GI-NEXT: cset w19, hs | |
| ; CHECK-GI-NEXT: adds x8, x8, x16 | |
| ; CHECK-GI-NEXT: add x9, x9, x10 | |
| ; CHECK-GI-NEXT: cset w10, hs | |
| ; CHECK-GI-NEXT: adds x8, x8, x29 | |
| ; CHECK-GI-NEXT: umulh x13, x4, x1 | |
| ; CHECK-GI-NEXT: cset w0, hs | |
| ; CHECK-GI-NEXT: adds x8, x8, x18 | |
| ; CHECK-GI-NEXT: and x10, x10, #0x1 | |
| ; CHECK-GI-NEXT: mul x16, x4, x22 | |
| ; CHECK-GI-NEXT: and x0, x0, #0x1 | |
| ; CHECK-GI-NEXT: umulh x18, x4, x22 | |
| ; CHECK-GI-NEXT: cset w4, hs | |
| ; CHECK-GI-NEXT: adds x8, x8, x9 | |
| ; CHECK-GI-NEXT: str x8, [sp, #112] // 8-byte Spill | |
| ; CHECK-GI-NEXT: cset w29, hs | |
| ; CHECK-GI-NEXT: adds x8, x11, x15 | |
| ; CHECK-GI-NEXT: cset w9, hs | |
| ; CHECK-GI-NEXT: cmn x8, x12 | |
| ; CHECK-GI-NEXT: ldr x11, [sp, #80] // 8-byte Reload | |
| ; CHECK-GI-NEXT: cset w8, hs | |
| ; CHECK-GI-NEXT: adds x12, x21, x17 | |
| ; CHECK-GI-NEXT: and x9, x9, #0x1 | |
| ; CHECK-GI-NEXT: cset w17, hs | |
| ; CHECK-GI-NEXT: adds x12, x12, x11 | |
| ; CHECK-GI-NEXT: and x8, x8, #0x1 | |
| ; CHECK-GI-NEXT: mul x21, x24, x1 | |
| ; CHECK-GI-NEXT: ldr x11, [sp, #56] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x8, x9, x8 | |
| ; CHECK-GI-NEXT: cset w9, hs | |
| ; CHECK-GI-NEXT: adds x12, x12, x2 | |
| ; CHECK-GI-NEXT: and x17, x17, #0x1 | |
| ; CHECK-GI-NEXT: mul x15, x24, x22 | |
| ; CHECK-GI-NEXT: cset w2, hs | |
| ; CHECK-GI-NEXT: adds x12, x12, x11 | |
| ; CHECK-GI-NEXT: cset w3, hs | |
| ; CHECK-GI-NEXT: adds x8, x12, x8 | |
| ; CHECK-GI-NEXT: and x9, x9, #0x1 | |
| ; CHECK-GI-NEXT: madd x27, x20, x22, x13 | |
| ; CHECK-GI-NEXT: cset w12, hs | |
| ; CHECK-GI-NEXT: adds x13, x13, x16 | |
| ; CHECK-GI-NEXT: str x8, [sp, #88] // 8-byte Spill | |
| ; CHECK-GI-NEXT: ldr x8, [sp, #64] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x9, x17, x9 | |
| ; CHECK-GI-NEXT: umulh x22, x24, x1 | |
| ; CHECK-GI-NEXT: and x4, x4, #0x1 | |
| ; CHECK-GI-NEXT: and x2, x2, #0x1 | |
| ; CHECK-GI-NEXT: add x9, x9, x2 | |
| ; CHECK-GI-NEXT: and x2, x3, #0x1 | |
| ; CHECK-GI-NEXT: madd x16, x6, x23, x30 | |
| ; CHECK-GI-NEXT: cset w30, hs | |
| ; CHECK-GI-NEXT: cmn x13, x21 | |
| ; CHECK-GI-NEXT: and x13, x19, #0x1 | |
| ; CHECK-GI-NEXT: mov x19, x26 | |
| ; CHECK-GI-NEXT: add x9, x9, x2 | |
| ; CHECK-GI-NEXT: umulh x21, x7, x14 | |
| ; CHECK-GI-NEXT: add x10, x13, x10 | |
| ; CHECK-GI-NEXT: cset w13, hs | |
| ; CHECK-GI-NEXT: adds x18, x22, x18 | |
| ; CHECK-GI-NEXT: add x11, x10, x0 | |
| ; CHECK-GI-NEXT: and x13, x13, #0x1 | |
| ; CHECK-GI-NEXT: mul x22, x7, x23 | |
| ; CHECK-GI-NEXT: cset w0, hs | |
| ; CHECK-GI-NEXT: adds x18, x18, x8 | |
| ; CHECK-GI-NEXT: cset w17, hs | |
| ; CHECK-GI-NEXT: adds x15, x18, x15 | |
| ; CHECK-GI-NEXT: and x18, x30, #0x1 | |
| ; CHECK-GI-NEXT: mul x10, x26, x14 | |
| ; CHECK-GI-NEXT: add x13, x18, x13 | |
| ; CHECK-GI-NEXT: cset w18, hs | |
| ; CHECK-GI-NEXT: adds x15, x15, x28 | |
| ; CHECK-GI-NEXT: and x17, x17, #0x1 | |
| ; CHECK-GI-NEXT: ldr x2, [sp, #32] // 8-byte Reload | |
| ; CHECK-GI-NEXT: umulh x30, x26, x14 | |
| ; CHECK-GI-NEXT: cset w28, hs | |
| ; CHECK-GI-NEXT: adds x26, x15, x13 | |
| ; CHECK-GI-NEXT: cset w15, hs | |
| ; CHECK-GI-NEXT: and x18, x18, #0x1 | |
| ; CHECK-GI-NEXT: umulh x8, x7, x23 | |
| ; CHECK-GI-NEXT: and x15, x15, #0x1 | |
| ; CHECK-GI-NEXT: madd x13, x7, x23, x21 | |
| ; CHECK-GI-NEXT: adds x21, x21, x22 | |
| ; CHECK-GI-NEXT: cset w22, hs | |
| ; CHECK-GI-NEXT: cmn x21, x10 | |
| ; CHECK-GI-NEXT: add x10, x11, x4 | |
| ; CHECK-GI-NEXT: and x11, x29, #0x1 | |
| ; CHECK-GI-NEXT: mul x3, x19, x23 | |
| ; CHECK-GI-NEXT: ldr x23, [sp, #8] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x10, x10, x11 | |
| ; CHECK-GI-NEXT: and x11, x12, #0x1 | |
| ; CHECK-GI-NEXT: and x12, x0, #0x1 | |
| ; CHECK-GI-NEXT: ldr x0, [sp, #120] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x9, x9, x11 | |
| ; CHECK-GI-NEXT: add x11, x12, x17 | |
| ; CHECK-GI-NEXT: cset w12, hs | |
| ; CHECK-GI-NEXT: adds x8, x30, x8 | |
| ; CHECK-GI-NEXT: mul x17, x6, x14 | |
| ; CHECK-GI-NEXT: add x10, x0, x10 | |
| ; CHECK-GI-NEXT: cset w0, hs | |
| ; CHECK-GI-NEXT: adds x8, x8, x2 | |
| ; CHECK-GI-NEXT: cset w2, hs | |
| ; CHECK-GI-NEXT: adds x8, x8, x3 | |
| ; CHECK-GI-NEXT: and x0, x0, #0x1 | |
| ; CHECK-GI-NEXT: and x2, x2, #0x1 | |
| ; CHECK-GI-NEXT: and x3, x22, #0x1 | |
| ; CHECK-GI-NEXT: and x12, x12, #0x1 | |
| ; CHECK-GI-NEXT: add x0, x0, x2 | |
| ; CHECK-GI-NEXT: cset w2, hs | |
| ; CHECK-GI-NEXT: madd x16, x6, x14, x16 | |
| ; CHECK-GI-NEXT: adds x8, x8, x17 | |
| ; CHECK-GI-NEXT: and x17, x2, #0x1 | |
| ; CHECK-GI-NEXT: add x12, x3, x12 | |
| ; CHECK-GI-NEXT: add x17, x0, x17 | |
| ; CHECK-GI-NEXT: cset w0, hs | |
| ; CHECK-GI-NEXT: add x11, x11, x18 | |
| ; CHECK-GI-NEXT: ldr x18, [sp, #24] // 8-byte Reload | |
| ; CHECK-GI-NEXT: ldr x22, [sp, #16] // 8-byte Reload | |
| ; CHECK-GI-NEXT: adds x8, x8, x12 | |
| ; CHECK-GI-NEXT: and x12, x28, #0x1 | |
| ; CHECK-GI-NEXT: and x0, x0, #0x1 | |
| ; CHECK-GI-NEXT: madd x18, x23, x25, x18 | |
| ; CHECK-GI-NEXT: add x11, x11, x12 | |
| ; CHECK-GI-NEXT: add x12, x17, x0 | |
| ; CHECK-GI-NEXT: cset w17, hs | |
| ; CHECK-GI-NEXT: ldr x2, [sp, #40] // 8-byte Reload | |
| ; CHECK-GI-NEXT: madd x3, x22, x5, x2 | |
| ; CHECK-GI-NEXT: and x17, x17, #0x1 | |
| ; CHECK-GI-NEXT: ldr x21, [sp, #48] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x11, x11, x15 | |
| ; CHECK-GI-NEXT: add x12, x12, x17 | |
| ; CHECK-GI-NEXT: madd x6, x24, x1, x27 | |
| ; CHECK-GI-NEXT: ldp x17, x15, [sp, #88] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldr x0, [sp, #104] // 8-byte Reload | |
| ; CHECK-GI-NEXT: add x12, x16, x12 | |
| ; CHECK-GI-NEXT: ldr x2, [sp, #72] // 8-byte Reload | |
| ; CHECK-GI-NEXT: madd x13, x19, x14, x13 | |
| ; CHECK-GI-NEXT: ldr x16, [sp, #112] // 8-byte Reload | |
| ; CHECK-GI-NEXT: eor x10, x10, x18, asr #63 | |
| ; CHECK-GI-NEXT: add x9, x0, x9 | |
| ; CHECK-GI-NEXT: add x11, x15, x11 | |
| ; CHECK-GI-NEXT: eor x17, x17, x3, asr #63 | |
| ; CHECK-GI-NEXT: mul x4, x21, x25 | |
| ; CHECK-GI-NEXT: eor x16, x16, x18, asr #63 | |
| ; CHECK-GI-NEXT: eor x9, x9, x3, asr #63 | |
| ; CHECK-GI-NEXT: eor x0, x26, x6, asr #63 | |
| ; CHECK-GI-NEXT: eor x11, x11, x6, asr #63 | |
| ; CHECK-GI-NEXT: mul x15, x2, x5 | |
| ; CHECK-GI-NEXT: orr x10, x16, x10 | |
| ; CHECK-GI-NEXT: orr x9, x17, x9 | |
| ; CHECK-GI-NEXT: eor x8, x8, x13, asr #63 | |
| ; CHECK-GI-NEXT: eor x12, x12, x13, asr #63 | |
| ; CHECK-GI-NEXT: cmp x10, #0 | |
| ; CHECK-GI-NEXT: mul x5, x20, x1 | |
| ; CHECK-GI-NEXT: orr x11, x0, x11 | |
| ; CHECK-GI-NEXT: csel x1, x18, x23, ne | |
| ; CHECK-GI-NEXT: csel x0, x4, x21, ne | |
| ; CHECK-GI-NEXT: cmp x9, #0 | |
| ; CHECK-GI-NEXT: orr x8, x8, x12 | |
| ; CHECK-GI-NEXT: mul x14, x7, x14 | |
| ; CHECK-GI-NEXT: csel x3, x3, x22, ne | |
| ; CHECK-GI-NEXT: csel x2, x15, x2, ne | |
| ; CHECK-GI-NEXT: cmp x11, #0 | |
| ; CHECK-GI-NEXT: ldp x22, x21, [sp, #192] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x4, x5, x20, ne | |
| ; CHECK-GI-NEXT: csel x5, x6, x24, ne | |
| ; CHECK-GI-NEXT: cmp x8, #0 | |
| ; CHECK-GI-NEXT: ldp x24, x23, [sp, #176] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: csel x6, x14, x7, ne | |
| ; CHECK-GI-NEXT: csel x7, x13, x19, ne | |
| ; CHECK-GI-NEXT: ldp x20, x19, [sp, #208] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldp x26, x25, [sp, #160] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldp x28, x27, [sp, #144] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: ldp x29, x30, [sp, #128] // 16-byte Folded Reload | |
| ; CHECK-GI-NEXT: add sp, sp, #224 | |
| ; CHECK-GI-NEXT: ret | |
| %o = call {<4 x i128>, <4 x i1>} @llvm.smul.with.overflow(<4 x i128> %a, <4 x i128> %b) | |
| %e0 = extractvalue {<4 x i128>, <4 x i1>} %o, 0 | |
| %e1 = extractvalue {<4 x i128>, <4 x i1>} %o, 1 | |
| %r = select <4 x i1> %e1, <4 x i128> %e0, <4 x i128> %a | |
| ret <4 x i128> %r | |
| } |